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.