1 / 34

Comp 401 Multiple Inheritance: Motivation and Issues

Comp 401 Multiple Inheritance: Motivation and Issues. Instructor: Prasun Dewan. Prerequisite. Inheritance Abstract Classes. Problem. A modification to the course problem. Want to gather statistics on how many times a course was searched How many times getTitle () was called.

juro
Télécharger la présentation

Comp 401 Multiple Inheritance: Motivation and Issues

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Comp 401Multiple Inheritance: Motivation and Issues Instructor: PrasunDewan

  2. Prerequisite • Inheritance Abstract Classes

  3. Problem • A modification to the course problem. • Want to gather statistics on how many times a course was searched • How many times getTitle() was called.

  4. Course Interface publicinterface Course { public String getTitle(); public String getDepartment(); publicintgetNumber(); }

  5. Logged Course Interface publicinterfaceLoggedCourseextends Course { publicintgetNumberOfQueries(); }

  6. ACourse publicabstractclassACourse { String title, dept; publicACourse (String theTitle, String theDept) { title = theTitle; dept = theDept; } public String getTitle() { return title; } public String getDepartment() { return dept; } }

  7. ALoggedCourse publicabstract classALoggedCourse extendsACourseimplementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super (theTitle, theDept); } publicintgetNumberOfQueries() { returnnumberOfQueries; } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } }

  8. Freshman Seminar Interface publicinterfaceFreshmanSeminarextends Course { public finalint SEMINAR_NUMBER = 6; }

  9. Logged Freshman Seminar Interface? publicinterfaceFreshmanSeminarextends Course { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedCourseextends Course { publicintgetNumberOfQueries(); } Code Duplication publicinterfaceLoggedFreshmanSeminarextendsLoggedCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminarextendsFreshmanSeminar { publicintgetNumberOfQueries(); }

  10. Single Inheritance Alternative 1 publicinterface Course { publicString getTitle(); publicString getDepartment(); publicintgetNumber(); } publicinterfaceLoggedCourse extendsCourse { publicintgetNumberOfQueries(); } publicinterfaceFreshmanSeminar extendsCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminarextendsLoggedCourse{ public finalint SEMINAR_NUMBER = 6; }

  11. Single Inheritance Alternative 2 publicinterface Course { publicString getTitle(); publicString getDepartment(); publicintgetNumber(); } publicinterfaceLoggedCourse extendsCourse { publicintgetNumberOfQueries(); } publicinterfaceFreshmanSeminar extendsCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminarextendsFreshmanSeminar{ publicintgetNumberOfQueries(); }

  12. Multiple Inheritance publicinterface Course { publicString getTitle(); publicString getDepartment(); publicintgetNumber(); } publicinterfaceLoggedCourse extendsCourse { publicintgetNumberOfQueries(); } publicinterfaceFreshmanSeminar extendsCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminar extendsFreshmanSeminar , LoggedCourse { } Multiple Inheritance Empty interface

  13. Multiple Class Inheritance? publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } } publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ … } ???

  14. Calling AFreshmanSeminar Constructor publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } } publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } } numberOfQueries uninitialized publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } }

  15. Calling Both Constructors publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } } publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } } ACourse constructor called twice publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } }

  16. ACourse publicabstractclassACourse { String title, dept; publicACourse (String theTitle, String theDept) { title = theTitle; dept = theDept; } public String getTitle() { return title; } public String getDepartment() { return dept; } } ACourse constructor called twice Does not cause a problem

  17. Alternative ACourse publicabstractclassACourse { String title, dept; staticintnumCourses; publicACourse (String theTitle, String theDept) { title = theTitle; dept = theDept; numCourses++; System.out.println(“A Course Created”); } public String getTitle() { return title; } public String getDepartment() { return dept; } publicstaticintgetNumCourses() { returnnumCourses: } } Does cause a problem constructor called twice Constructor is not idempotent

  18. Idempotent vs. Non Idempotent publicACourse (String theTitle, String theDept) { title = theTitle; dept = theDept; } publicACourse (String theTitle, String theDept) { title = theTitle; dept = theDept; numCourses++; System.out.println(“A Course Created”); } Some procedures are also Idempotent operation: Calling the operation 1 time has the same effect as calling it successfully an arbitrary number of times All functions without side effects are idempotent

  19. Multiple Class Inheritance Issues Which superclass constructors should be called? Calling constructor of only one of the superclasses can leave variables of other superclasses uninitialized Calling constructors of all superclasses can result in constructor of some common superclass of the superclasses to be called twice If constructor is not idempotent, we are likely to get results the writer of the idempotent constructor did not expect What if we forced constructors to be idempotent – can we allow multiple inheritance?

  20. Multiple Class Inheritance Issues What if we forced constructors to be idempotent and call all inherited constructors – can we allow multiple inheritance? Non constructor methods?

  21. Inheriting Non Constructor Functions publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } publicvoid print() { System.out.println(“Seminar”); } } Call all inherited methods and force them also to be idempotent? publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } publicvoid print() { System.out.println(“Logged”); } } If we special case non constructors, which one of these should be called? publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } }

  22. Inheriting Non Constructor Functions publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } public String toString() { return“Seminar”; } } Function cannot return multiple values, so must have different rules for them and constructors publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } public String toString() { return “Logged”; } } Which function should be inherited? publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } }

  23. Dominant-Recessive Rules: Choose First Superclass? publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } public String toString() { return“Seminar”; } } Confusing to use order as in imports publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } public String toString() { return “Logged”; } } Java does not support multiple inheritance for interfaces but not classes publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } }

  24. Inheriting through Different Paths publicinterface Course { publicString getTitle(); publicString getDepartment(); publicintgetNumber(); } publicinterfaceLoggedCourse extendsCourse { publicintgetNumberOfQueries(); } publicinterfaceFreshmanSeminar extendsCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminar extendsFreshmanSeminar , LoggedCourse { } Same method headers inherited twice, no problem

  25. Inheriting Equal Headers publicinterface Course { publicString getTitle(); publicString getDepartment(); publicintgetNumber(); } publicinterfaceLoggedCourse extendsCourse { publicintgetNumberOfQueries(); public String getTitle(); } publicinterfaceFreshmanSeminar extendsCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminar extendsFreshmanSeminar , LoggedCourse { } Equal method headers inherited twice Interface = set of headers, removes duplicates

  26. Inheriting Headers with Different Return Types publicinterface Course { publicString getTitle(); publicString getDepartment(); publicintgetNumber(); publicintinitTitle(String initVal); } publicinterfaceLoggedCourse extendsCourse { publicintgetNumberOfQueries(); publicvoid initTitle(String initVal); } publicinterfaceFreshmanSeminar extendsCourse { public finalint SEMINAR_NUMBER = 6; } publicinterfaceLoggedFreshmanSeminar extendsFreshmanSeminar , LoggedCourse { } Overload conflict, inheritance not allowed

  27. Multiple inheritance rules • Allow interfaces to inherit multiple times • Only headers are inherited • Do not allow classes to inherit multiple times (Java) • Can be confusing to programmers • Other solutions • Allow multiple inheritance if ambiguity does not arise • If ambiguity arises indicate which implementation is used (C++) • ALoggedCourse.toString() vsAFreshmanSeminar.toString() • Choose one or none of the bodies if problem arises • Based on order in extends clause? • extends ALoggedCourse, AFreshmanSeminar

  28. Repeating Code publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } } publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } } publicclassALoggedFreshmanSeminarextendsALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } }

  29. Reduced Polymorphism? staticvoidprocessClass (AFreshmanSeminarcourse) { … } processClass (newALoggedFreshmanSeminar(“Random Thoughts", "CS")); staticvoidprocessInterface (FreshmanSeminarcourse) { … }  processInterface(newALoggedFreshmanSeminar(“Random Thoughts", "CS"));

  30. Single inheritance => reduced polymorphism? • Yes, if classes used to type variables • Interfaces offer solution to lack of multiple (class) inheritance in Java • Most programmers do not realise other uses. • In text books, interfaces introduced and used only in problems requiring multiple inheritance

  31. Implementing Multiple Interfaces vs. Single Extended Interface publicclassALoggedFreshmanSeminarextendsALoggedCourse implementsLoggedFreshmanSeminar{ … } processInterface ( newALoggedFreshmanSeminar(“Random Thoughts", "CS")); publicclassALoggedFreshmanSeminarextendsALoggedCourse implementsLoggedCourse, FreshmanSeminar{ … } processInterface ((FreshmanSeminar) newALoggedFreshmanSeminar(“Random Thoughts", "CS")); staticvoidprocessInterface (FreshmanSeminarcourse) { … }

  32. Does not require casting to use different interfaces of same object Modulo overloading problems These arise whenever an object can be typed in multiple ways. A compile time issue – these casts are needed only at compile time and do not lead to runtime errors. Implementing multiple interfaces vs. Single Interface

  33. How to Avoid Code Duplication publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } } publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } } IS-A IS-A publicclassALoggedFreshmanSeminar extendsAFreshmanSeminar, ALoggedCourse implementsLoggedFreshmanSeminar{ publicALoggedFreshmanSeminarString theTitle, String theDept) { super(theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } }

  34. How to Avoid Code Duplication? publicclassAFreshmanSeminarextendsACourse implementsCourse { public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); } public intgetNumber() { return SEMINAR_NUMBER; } } publicabstract classALoggedCourseextendsACourse implementsLoggedCourse { intnumberOfQueries = 0; publicALoggedCourse (String theTitle, String theDept) { super(theTitle, theDept); } public String getTitle() { String retVal = super.getTitle(); numberOfQueries++; return retVal; } publicintgetNumberOfQueries() { returnnumberOfQueries; } } HAS-A IS-A public class ALoggedFreshmanSeminarextends ALoggedCourse implements LoggedFreshmanSeminar{ FreshmanSeminar seminar; public ALoggedFreshmanSeminar(String theTitle, String theDept) { super (theTitle, theDept); seminar= new AFreshmanSeminar(theTitle, theDept,); } public intgetNumber() { return seminar.getNumber(); } }

More Related