4

I am using PHP and designing some abstract classes.

I can declare properties with constant values within my abstract class and access/overwrite them from any class which extends this without re declaring them within any of the extending classes.

A benefit to this is less repetitive typing but the downside that overtime the original structure/layout of these abstract properties is forgotten and could be left at there default static values or even forgotten(not used) completely.

How is this handled in professional environments? I assume this has been thought out before and is either favored or isn't?

I am trying to adhere to good OOP principles/rules such as SOLID, DRY and KISS but I haven't seen this specific issue talked about in these. (perhaps I missed it when researching?)

  • declare properties with static values within my abstract class do you mean static in the context of a static (class) variable, or in the context of "unchanging" as opposed to dynamic? Seems like a class variable could be a really bad idea there. – user22815 Apr 22 '14 at 16:18
  • @JohnGaughan I meant static in the sense like var $name = 'John';(static) var $time = date();(dynamic). Perhaps I should have said constant value. I will edit my post. – cecilli0n Apr 22 '14 at 23:17
2

This may be a personal preference, but I avoid having base classes for the sake of sharing properties. Particularly in data classes. I don't mind the repetition, and I avoid locking my classes into a fixed "data" hierarchy.

There are enough problems with inheritance, particularly over time as the code base grows, that I am reluctant to share methods through a class hierarchy, and even more reluctant to share properties through a class hierarchy.

...

Hm. I just noticed that you mentioned "static" properties. Rather than static (i.e. global) properties in a base class, you're better off with a separate, single instance of something dispensed by a factory. Make sure you provide for concurrency to avoid race conditions.

  • Methods are a different matter. Abstract classes are a great place to put common methods. Properties are fine so long as you are sure that they are "universal" to the class hierarchy. – Robert Harvey Apr 22 '14 at 15:43
  • I agree, you are asking for trouble to allow derived classes to modify static member data. Who is to say they will modify it correctly so it doesn't break other derived classes/instances. However, if that static data is completely managed by the base class and can only be modified by the base class under well defined conditions then there could be some potential good uses. – Dunk Apr 22 '14 at 15:57
  • @RobertHarvey The properties are definitely universal, should I always put these in the abstract class? – cecilli0n Apr 22 '14 at 15:58
  • You put the properties in the abstract class if you want them to be shared among all of the descendant classes. – Robert Harvey Apr 22 '14 at 15:59
  • 3
    I certainly think you have to be judicious about what you put there. In theory, inheritance provides a structural hierarchy for your program; in practice, most folks tend to use composition instead. I use abstract classes when I need a home for some common functionality, and not for much else. But I exercise restraint, and I expect the other team members to do the same. – Robert Harvey Apr 22 '14 at 17:28
0

To answer your question, yes. If the abstract class is the logical place for the property then put it there. Use the tools that classes and OOP gives you.

"overtime the original structure/layout of these abstract properties is forgotten and could be left at there default static values or even forgotten(not used) completely."

This implies to me that developers using/creating the abstract class or child classes are required to do something with these properties. If that is true, try to come up with a class design that forces a developer to deal with this. That's better then to trust everyone to always do it correctly.

You mention changing static values. Static properties are shared between all class instances, so by changing their value in one object you change it for all. Multiple objects changing global state is something you want to avoid, because it is difficult to keep all changes in the correct order.

0

If you keep your inheritance shallow (the opposite of lasagna) then there is nothing philosophically wrong with putting properties in an abstract class. The language, after all, allows it. Keeping your inheritance shallow will ensure those properties aren't forgotten.

The only thing about this you might want to seriously consider though is making those properties protected. Inheriting classes can always loosen the visibility, but otherwise if at some point you need to make a public property into a protected one you are out of luck.

When designing an abstract class, you may want to ask yourself:

  • Are there a lot of properties?
  • How many classes will inherit this? 3? 15? 100?
  • Am I declaring any abstract methods (such as leftovers from partial interface implementations)?
  • Does this abstraction tie together two or more otherwise unrelated classes?

If not many classes will inherit from it or it creates a relationship where there would otherwise be none then chances are you can do what you're trying to do with traits.

An example would be Model vs ActiveRecord; "form vs feature".

  • ActiveRecord can provide scaffolding/partial implementation for a CRUD interface (like a $table property, a static::load($id) method, etc).
  • Model might have built-in helper functions or an abstract validate() method, and can't instantiate on its own.
  • Not all Models are ActiveRecords, and vice versa.

ActiveRecord would be best as a trait, as it applies horizontally throughout the application. Models on the other hand have a definite hierarchy and would work best as an abstract.

0

This is the classical use case for favor composition over inheritance. If some properties belong closely together, than put them in a class of their own. Then you only need one property that references that class instead of having repeated properties all over the place. You then can get rid of the complete class hierachy.

Also mind that abstract classes are about abstracting behavior. If a getter is the behavior of your class, than it might be ok to have an abstract class with a getter (same applies for setter). But it mostly makes no sense from a behavioral perspective to have the getter and setter for the same property in the same base class, since that just leaves no room for behavioral abstractions.

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.