CSc 520Principles of Programming Languages47: OO Languages — Multiple InheritanceChristian CollbergDepartment of Computer ScienceUniversity of [email protected] 2005 Christian CollbergApril 22, 20051 Multiple Inheritance• In some languages (C++, Eiffel) a class can have more than one superclass.class Person { Name : STRING; }class Student extends Person {Advisor : Teacher;}class Teacher extends Person {Salary : INTEGER;method Rich () : BOOLEAN;return Salary > 50000;}class Tutor extends Student, Teacher {Boss : Teacher;}2 Multiple Inheritance. . .class Teacher extends Person {Salary : INTEGER;method Rich () : BOOLEAN;return Salary > 50000;}Rich() should translate into:PROCEDURE Rich (SELF : Teacher) : BOOLEAN;RETURN SELF^.Salary > 50000;13 Multiple Inheritance. . .• We’d like to be able to call m.Rich() for any Teacher object, including a Tutor:PROCEDURE Rich (SELF : Teacher) : BOOLEAN;RETURN SELF^.Salary > 50000;Teacher Knuth = new Teacher;Tutor Lucy = new Tutor;boolean k = Knuth.Rich()boolean l = Lucy.Rich()• In order for this to work, the Salary field in a Tutor record must be at the same offset as the Salaryfield in the Teacher record.4 Multiple Inheritance. . .• But, if our record layout uses simple concatenation of parent classes (like with single inheritance), weget:Person0:Name:String0:Name:String4:Salary:INTTeacher0:Name:String4:Advisor:TeacherStudentTutor8:Salary:INT0:Name:String4:Advisor:TeacherFrom StudentFrom Teacher• The Salary field in a Teacher record is at offset 4, but the Salary field in the Tutor record is at offset8.5 Multiple Inheritance. . .• An inefficient implementation might do:PROCEDURE Rich (SELF : Teacher) : BOOLEAN;RETURN IF ISTYPE(SELF,Teacher)THEN (SELF-4)^>50000 ELSE (SELF+8)^>50000;• Or we could insert extra space to align the fields properly:2Person0:Name:String0:Name:String4:Advisor:Teacher8:Salary:INTTutor0:Name:String4:Advisor:TeacherStudent0:Name:String8:Salary:INTTeacher4:Wasted:4−bytes6 Multiple Inheritance. . .• With multi-directional layouts, we place variables at both positive and negative offsets:0:Name:String4:Advisor:TeacherStudent−4:Salary:INT0:Name:String4:Advisor:TeacherTutorPerson0:Name:StringTeacher0:Name:String−4:Salary:INT7 Multiple Inheritance. . .0:Name:String4:Advisor:TeacherStudent−4:Salary:INT0:Name:String4:Advisor:TeacherTutorPerson0:Name:StringTeacher0:Name:String−4:Salary:INT• The Salary-field is always at the same offset, regardless of what type of object:PROCEDURE Rich (SELF : Teacher) : BOOLEAN;RETURN (SELF-4)^>50000;8 Multiple Inheritance. . .• How does the language deal with the same field inherited through more than one path? A Tutorinherits Name twice, once from Student and once from Teacher:class Person { Name : STRING; }class Student extends Person {· · ·}class Teacher extends Person {· · ·}class Tutor extends Student,Teacher {· · ·}3• Should Tutor have one or two copies of Name?• In Trellis/Owl you always get just one copy of Name.• In C++ you can choose. If you declare a superclass virtual, Tutor only gets one copy of Name, otherwisetwo.9 Multiple Inheritance. . .• How does the language deal with different fields/methods with the same type/signature inherited fromdifferent classes?class Student {Name : STRING; · · · }class Teacher {Name : STRING; · · · }class Tutor extends Student,Teacher {· · ·}Tutor T = new Tutor();T.Name = "Knuth"; /* Which Name? */10 Multiple Inheritance. . .class Student {Name : STRING; · · · }class Teacher {Name : STRING; · · · }class Tutor extends Student,Teacher {· · ·}Tutor T = new Tutor();T.Name = "Knuth"; /* Which Name? */• In Eiffel, the programmer has to rename fields until there are no more conflicts, using a renameclause:class Tutor extends Student,Teacher rename Name⇒TName {· · ·}• In C++, conflicts are resolved when the field/method is used:Tutor T = new Tutor();Teacher::T.Name =
View Full Document