0

If I have an abstract Animal class with a $name property and constructor like this:

abstract class Animal {

   protected $name;

   public function __construct($name) {
      $this->name = $name;
   }
}

And the classes who are instance of the Animal class uses make use of the $name property like this:

class Cat extends Animal {

   public function makeNoise() {
      switch($this->name) {
        ....
      }
      return "Meow";
   } 

   //More functions who will be using the $this->name property
}

Is it better to use an protected getter method in the class or stay with the protected property?

  • Why is there a switch on name if you are already using polymorphism? What do you think the benefits and drawbacks of each approach are? – user22815 Feb 10 '15 at 15:44
  • @Snowman That was just a quick example, it can be anything. – Bas Feb 10 '15 at 15:45
  • 2
    Worth noting that in PHP, property is a class member variable, i.e. what is called a field in other languages such as C#. Therefore, the term is used correctly in the question. – Arseni Mourzenko Feb 10 '15 at 15:45
  • @Snowman I dont actually get it :) can you explain it more why i should't do that? – Bas Feb 10 '15 at 15:48
  • @Bas think about what each class represents and how the make noise function would work for that class. If you have a specific class for a cat, do you already know what noise it would make? Would you need to still switch on the name? – Jetti Feb 10 '15 at 15:50
1

There are points to keep in mind for each approach, and there may not be a clear winner.

Protected Field

If not constant, a protected field allows the subclass to modify parent class state directly. This means a subclass may be able to violate the parent's invariants or validations. State may be able to change at inopportune times, which may cause problems (or it may not).

In other words, this approach might cause a class to behave inconsistently, possibly in a bad way.

That being said, some state might be treated as volatile and it is okay for it to change whenever you want.

Getter

This is actually not much different. Methods can be overridden as long as they are not marked as un-overridable (e.g. final, non-virtual). The difference is while a field can be changed directly, a getter/setter combination can enforce invariants and validations on the field transparently.


Does the state represent a property of the base class directly, or does it happen to be that all subclasses need the state but it does not really belong to the base class? For example, let as assume that all animals can speak. Animal knows it can speak, but the how belongs in the subclass. Maybe an abstract getter method is appropriate: Animal can use it, but the actual implementation must be defined in each subclass.

If the state does not change, you may also be able to define a constant in the base class. Maybe the subclass passes a value to the base class constructor which then sets it in stone in that constant. This allows the base class to use the constant as well because it is defined in the base class.

There is no one way to do this, and understanding the right way for a given situation requires experience. Hopefully this helps explain why each option works and how they are different.

  • Thank you, this animal class was just an example and it's all about the properties at the moment. But, the $name property is in this case read only, i dont need to change it. – Bas Feb 10 '15 at 16:23
  • @Bas: If I have direct access to the base-class properties, there is very little from stopping me changing $name property anyway. – Bart van Ingen Schenau Feb 10 '15 at 16:32
  • @BartvanIngenSchenau What do you mean? – Bas Feb 10 '15 at 18:53
  • @Bas: How are you going to prevent me from writing a class SuperCat extends Animal in which I do have a line this->$name = "Overwritten";? – Bart van Ingen Schenau Feb 10 '15 at 19:09
  • @BartvanIngenSchenau Not, but is it good practice while your use will be only for read-only?^^ I would never have to change that vaule. – Bas Feb 10 '15 at 19:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.