In sports, training coaches sometimes forbid to use some play element. In OOP classes there should be an assignment to design a system without inheritance. Just to show what is most important in OOP.
I was taught OOP using Modula-2 in 1989, by defining structures and functions that took a pointer to the struct as first parameter. No inheritance goodies! I used that style in C until 1996 when I definitely moved to C++. Probably why I am not terribly dismissive of OOP but very much of things like inheritance trees, the Java OOP style, and the overuse of GoF in architecture, literature and especially programming discussions.
Person HAS A IEmploymentRelationship
ContractEmployment IMPLEMENTS IEmploymentRelationship
FullTimeEmployment IMPLEMENTS IEmploymentRelationship
FullTimeEmployment HAS A IDirectReport
Manager HAS A Person
Manager IMPLEMENTS IDirectReport
And then salary() is a polymorphic function declared by the IEmploymentRelationship interface, where FullTimeEmployment instances use the manager somehow, and ContractEmployment doesn't.
You can even put some sugar on that by having a salary() function on Person that calls the salary() function on its IEmploymentRelationship—but I wouldn't, for the same reason I wouldn't denormalize a relational database.
Comments
In sports, training coaches sometimes forbid to use some play element. In OOP classes there should be an assignment to design a system without inheritance. Just to show what is most important in OOP.
I was taught OOP using Modula-2 in 1989, by defining structures and functions that took a pointer to the struct as first parameter. No inheritance goodies! I used that style in C until 1996 when I definitely moved to C++. Probably why I am not terribly dismissive of OOP but very much of things like inheritance trees, the Java OOP style, and the overuse of GoF in architecture, literature and especially programming discussions.
How would you design something like :
Person --> Full Time Employee --> Manager
Person --> Contract Employee
Without inheritance assuming that salary calculation is the only thing which differentiates them.
Something like...
And then salary() is a polymorphic function declared by the IEmploymentRelationship interface, where FullTimeEmployment instances use the manager somehow, and ContractEmployment doesn't.You can even put some sugar on that by having a salary() function on Person that calls the salary() function on its IEmploymentRelationship—but I wouldn't, for the same reason I wouldn't denormalize a relational database.
Got it. Thank you.
In Ada, I remember reading that you can limit the inheritance depth.