Am I doing polymorphism the right way?

Asked

Viewed 103 times

1

I have a major sales class, and other subclasses that would inherit the sales class.

I thought of using polymorphism, in addition to using common methods as inheritance, I thought of injecting individual behaviors of each subclass calling even so the parent method.

Example:

class vendas {
    public function save(x) {
        return x+x;
    }
}

class pdv extends vendas {
    public function save(x) {
        //Comportamento injetado devido a particularidade da classe pdv
        $this->validarXPdv(x)
        
        //Utilização do metodo herdado
        return parent::save(x);
    }

     public function validarXPdv(x) {
       ...
    }
}

Would that be a bad practice? Would there be any alternative?

3 answers

4


This is conceptually wrong, and using the term you used in the question, it’s a bad practice (although I don’t like it because it makes people think it’s a magic rule). At least that’s what I can tell by assessing what’s in the question, which forces me to infer certain things. I mean, without proper information, you can’t really answer that.

People think object orientation is using the basic mechanisms heritage, polymorphism and encapsulation (that people don’t even understand what it is and do something else), but actually it’s making the object have meaning and if those mechanisms served that, great. So just knowing if you have a common method is not enough to define if the inheritance is adequate. I can have one save() in Pdv as much as in Relatorio, or Texto, or Banco, or Abobrinha which have nothing to do with Pdv.

Contrary to what people think, inheritance does not serve to take any methods from other classes, it serves to show that there is a clear relationship between these type definitions. Inheritance is just one way to do it. It’s not to take something meaningless and inherit.

With artificial examples like Vendas who has a save() that does not do something useful, or something that works biologically and is a clear heritage, but which is not in practice in any system (other than biology) people cannot learn what they actually need to do in a real system.

This is well defined by Liskov. Inheritance only occurs when an object has a clear classification above it that fully defines what it is. It is said that the object is a another object.

Pdv is not a Vendas. A PDV makes sales, but it’s not one, so there’s no point in having inheritance just by name. What if it’s not giving proper names to things to which object-oriented programming? This is fundamental in this paradigm.

But I want to point out that you can’t even respond properly because even in this class Vendas nor in the supplement of the question does it say what it’s for, and you can’t program it properly like this.

It seems you don’t need inheritance there, but if you need it, it has to be with a class that generalizes what is a Pdv, not to say that he has something useful for this PDV.

It gets even worse than Vendas is final and cannot be inherited, there is completely wrong.

Inheritance is not created to inject what you need into the object.

It is possible to use a trait to inject behaviors into a class. But it needs to be done with discretion, if it’s just a mechanism to use something that already exists, it’s wrong, it needs to have semantics, you need to see where you’re going to use it, because it’s only useful if in some places you get this trait to do this particular operation, and this behavior is always the same, which I doubt it will be in this case. But again, I could only say if I knew the whole context. When you don’t have all the right requirements the code will go wrong by definition.

So it takes a global understanding of the specific problem and of the whole object orientation, it’s not a cake recipe that will make you get it right. It is easy to say that this case is old, but this does not mean that other situations will be like this, even for everything has exception. This is a case that seems to cause a unnecessary coupling and makes the object less cohesive.

  • Thank you for your reply Ending, I will study about what commented, the class Sales, would be a main crud, could have used in the example Crudvendas, but my idea is that anyone who wanted to use a function of Crudvendas, can add behaviors without rewriting all code.

  • 1

    It seems wrong. This is usually a classic mistake of inheritance, but it always depends on many details.

2

It is not a bad practice no, as long as it is well structured as to the context and responsibility. This means, do not add methods in the superclass to force behavior in subclasses that is unnatural to their context of use.

Another possibility, thinking in context and that PHP does not have multiple inheritance, would be to use Traits to add functionality to child classes.

I will use the good old example of inheritance with animal classes.

Imagine a superclass animal, which has the eating method, ok all animals eat, but, as they eat differently from each other in large groups, for example mammals in relation to birds, we would use your solution calling the superclass method when superimposed the eating method in the subclasses, of course, when necessary to reuse the superclass behavior and specialize it in the sub.

Now think about the case of birds that don’t walk but jump, we can’t add the method of walking in animals because it would be a problem for birds, but mammals do, for the most part. How to solve? Traits, we could add the method locomover, abstract in animal, or create a Trait Walk and use it only in the walking anomas, for example, duck is a bird and walk.

Something like this with the example of locomotion behavior:


Class Animal {
   function locomover(){...}

   function comer() {...}
}

Class Ave extends Animal {
   function comer() {
      parent::comer();
      // complemento da lógica
   }

   function voar() {...}

   function locomover() {
      $this->voar();
   }
}

Trait PodeAndar {
   function andar() {
      ...
   }
}

Class Pato() extends Ave {
   use PodeAndar; // automaticamente pato além de voar e locomover, agora possui o método andar também
}
  • Thanks for the answer, I’ll take a look at Trait’s, see if I can take advantage.

0

In addition, a reply I found in the book Design standards, Chapter 5, page 301, on Pattern Template Method, where the following is highlighted in the text: inserir a descrição da imagem aqui

Or maybe my point of view is not so wrong, in my example I simplified a relationship like sales.

  • Carefully review the response of Maniero. To name a class "sales" is an incoherent attitude from the point of view of object orientation. What are the responsibilities of this class? What does this class propose to do? The passage you have put on method template presupposes that the standard, like all standards, is being used in the right place and the right way, this is not necessarily true if the purpose of sales class is unclear. Maybe you should inject in the POS (pass via constructor) an instance responsible for data access (but with a better name than "sales").

Browser other questions tagged

You are not signed in. Login or sign up in order to post.