By approaching with the concept and mechanism of inheritance it is possible to notice how it guides us from more generic classes into specialized ones, based on the project's specifics.
Inheritance is potentially infinite; only our needs (and computer's memory) can put a stop to the chain of children.
In any case what we learned is that the public and private attributes are inherited as they are: respectively public and private.
[But while the former are accessible, the latter aren't!]
The other aspect we talked about relates to necessity of specializing the new classes with new attributes and/or methods: a special setting wants a method to be shared among the father and the children classes, so that it can be declared virtual in the first.
It's required when a method, enough for the father which is initially designed for, becomes a base for the children where to be redeclared.
In the last article we saw the printing method, for the employees and the workers: a two-levels hierarchy, the simplest case of inheritance.
And if you remember (but you read it first? :)) we avoided to add a button, onto the form, bound to the redeclared method in the Worker class, because it would have been redundant; in facts it would have been same as using the direct Worker's printing method.
But as previously said, the chain keeps going on according to our needs, so we can imagine to design a class which inherits from Worker, by specifying if we're dealing with a part-time worker for example.
What happens now?
Simply we have a third class, the last in a logical hierarchy, which derives from the second one who descends from the first one: to be short, the PrintMeVirtual() virtual method can be redeclared in the third one too; and it has worthwhile even if WorkerPartTime only uses Worker, without Employee.
In other words the third class has now two fathers, the first of which has the precedence.
[Notice that "can be redeclared" and not "must be"]
type TWorkerPartTime = class(TWorker) //SOS !!! WorkerPartTime Inherits from Worker. (inherited) private //PRIVATE ZONE (Only the Class employee can SEE this zone) protected //PROTECTED ZONE (Only the Class employee and his children can SEE this zone) NumberOfWorkingDays: integer; public //PUBLIC (Anyone can see this zone) ... function PrintMe():string; //Public Object Method function PrintMeVirtual():string; override; //Sos !!! Try to remove override to see what happens !!! (becomes like the normal print) end; implementation ... //Object Method function TWorkerPartTime.PrintMe():string; begin result:= 'The selected worker parttime has Id : ' + inttostr(self.Id) + ' ,name : ' + self.Name + ' , surname : ' + self.SurName + ' and working hours : ' + inttostr(self.WorkingHours) + ' and working days : ' + inttostr(self.NumberOfWorkingDays) + #13#10; end; //Object Method function TWorkerPartTime.PrintMeVirtual():string; begin result:= '(Virtual print) The selected worker parttime has Id : ' + inttostr(self.Id) + ' ,name : ' + self.Name + ' , surname : ' + self.SurName + ' and working hours : ' + inttostr(self.WorkingHours) + ' and working days : ' + inttostr(self.NumberOfWorkingDays) + #13#10; end;
[With the virtual printing method here in WorkerPartTime we have the same situation of Worker; it would be redundant.]