1 / 120

Object-Oriented Programming (Java), Unit 13

Object-Oriented Programming (Java), Unit 13. Kirk Scott. Inheritance, Part II. 13.1 Abstraction in Class Design 13.2 Polymorphism and Dynamic Binding 13.3 Multiple Inheritance and Interfaces 13.4 An Example from the Java API: The Point Classes. Hieronymus Bosch

stesha
Download Presentation

Object-Oriented Programming (Java), Unit 13

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. Object-Oriented Programming (Java), Unit 13 Kirk Scott

  2. Inheritance, Part II • 13.1 Abstraction in Class Design • 13.2 Polymorphism and Dynamic Binding • 13.3 Multiple Inheritance and Interfaces • 13.4 An Example from the Java API: The Point Classes

  3. Hieronymus Bosch • The Garden of Earthly Delights

  4. Auguste Rodin • The Thinker

  5. M. C. Escher • Relativity

  6. 13.1 Abstraction in Class Design

  7. 13.1.1 The Level of Implementation of Object Characteristics in a Class Hierarchy, and Whether Instances of Classes Should be Allowed • Inheritance leads to two important questions. • Where should instance variables and methods be implemented in an inheritance hierarchy? • Are there classes which should never have instances of them constructed?

  8. 13.1.2 An Example of Needless Duplication—Implementation Too Low in the Hierarchy • The assignment for Unit 12 involved a hierarchy of Food classes. • The complete UML diagram for the requested classes is shown on the next overhead.

  9. PackagedFood and BulkFood are both subclasses of Food

  10. The written instructions for the classes in the Unit 12 assignment specified that both PackagedFoodV4 and BulkFoodV4 have a String variable named units. • That means that if you expressly followed the instructions, both classes would contain code such as that shown on the following overhead.

  11. private String units; • … • public void setUnits(String unitsIn) • { • units = unitsIn; • } • public String getUnits() • { • return units; • }

  12. Having this code in both classes is unnecessary repetition. • Common elements such as the instance variable units and its get and set methods should be implemented in a superclass and inherited.

  13. The statements on the previous overhead give an indication of the answer to the question posed at the beginning: • Where should instance variables and methods be implemented in an inheritance hierarchy? • Attributes and operations should be implemented at the highest level possible in an inheritance hierarchy.

  14. 13.1.3 A Logical Explanation of Whether Instances should be Allowed • Take a look at this inheritance hierarchy again: • Kingdom: Animalia • Phylum: Chordata • Class: Mammalia • Order: Primates • Family: Hominidae • Genus: Homo • Species: sapiens

  15. In the biological world, every kind of animal can ultimately be described as a single species. • There can be instances of Homo sapiens. • There can be no instances of the superclasses. • There can be no instance of Animalia, for example, because there is no such thing as a generic animal.

  16. Consider the hierarchy of classes in the exercises from the previous unit again. • Does it make sense to create instances of the Food class, or only instances of the classes PackagedFood and BulkFood? • If there is no such thing as a food which is not a packaged food or a bulk food, then there should be no instances of the Food class. • There should only be instances of the PackagedFood or the BulkFood classes.

  17. The statements on the previous overhead give an indication of the answer to the second question posed at the beginning: • Are there classes which should never have instances of them constructed? • The answer is yes, some classes should never have instances of them constructed.

  18. The questions of where to implement features and whether classes should have instances are related. • Some classes exist for the purposes of categorizing elements of a hierarchy. • They categorize by means of the fact that they gather together certain characteristics which all of their subclasses should have. • However, those classes which simply categorize would not have instances themselves.

  19. 13.1.4 Trying to Provide a Method in Java for Classes Which Would Have Different Implementations of it • Suppose you wish all classes in the food hierarchy to implement the getUnitCost() method. • In theory, it would be desirable to implement a method common to all of the classes in the hierarchy in the Food class, at the top of the hierarchy. • Because the unit cost is computed differently for the two subclasses, the method would have to be overridden in each.

  20. It is desirable to be able to specify that a given method exist for all classes in an inheritance hierarchy while having a separate implementation in each. • Two undesirable ways of accomplishing this are given on the following overhead.

  21. 1. You could implement one of the subclass versions in the superclass. • Then the method would only have to be overridden in the other subclass. • 2. You could declare a method in the superclass with an empty body, containing no code. • Then you would have override the method with real (and differing) implementations in both of the subclasses.

  22. In either case the method as implemented in the superclass could not be correctly called on objects of the superclass. • This is why these two solutions are undesirable. • In the first case it would be a method implementation that applied to just one of the subclasses, not a common implementation for all. • In the second case it would be a dummy implementation of no use at all.

  23. 13.1.5 The Best Solution: An Abstract Method in the Superclass—Forcing the Class Itself to be Abstract • The correct solution is to declare the method in the superclass to be abstract. • An abstract method has no braces or body and contains no code. • It does specify a return type and a parameter list. • It would appear in the Food class as follows: • public abstract double getUnitCost();

  24. Declaring a method abstract has three critical effects: • If a class contains an abstract method, the class itself has to be declared abstract • It is not possible to construct instances of an abstract class. • It requires that the method be overridden in each immediate, concrete subclass.

  25. In this example, the Food class would have to be declared in the following way: • public abstract class Food

  26. 13.1.6 Abstract Classes can still have Constructors • An abstract class groups together sets of attributes and operations which are to be shared by its subclasses. • It is not possible to construct instances of an abstract class in a user program. • However, an abstract class may contain constructors • Remember that constructors in the concrete subclasses of an abstract class may depend on the existence of constructors in the superclass.

  27. 13.1.7 Example Code • The code for the food classes, rewritten using abstraction, will be given shortly. • They will be version 5 of the classes, V5. • Unit 12 ended with V3 and the unit 12 assignment asked you to write V4. • FoodV5 will be an abstract class. • The getUnitCost() method is declared abstract in FoodV5. • The implementations of the method in the packaged food and bulk food subclasses will differ.

  28. The getUnitCost() method for a packaged food, PackagedFoodV5, calculates the unitCost by dividing the itemCost by the size. • The getUnitCost() method for a bulk food, BulkFoodV5, is a simple get method which returns the value of the unitCost instance variable.

  29. In the previous unit, in the Food/TaxedFood hierarchy, the setMarkupToThisMarkup() method was given • The FoodV4 class included a setBrandToThisBrand() method—which you should have provided as part of the unit 12 assignment • The Food/BulkFood/PackagedFood hierarchy under consideration in this unit will continue to use the setBrandToThisBrand() method

  30. When looking at the example code, keep these points in mind: • An abstract class will most likely have instance variables and get and set methods, which will be inherited, as usual. • It may also have methods like setBrandToThisBrand(), which will also be inherited, as usual.

  31. public abstract class FoodV5 • { • private String brand; • private String productName; • private String units; • public FoodV5(String brandIn, String productNameIn, String unitsIn) • { • brand = brandIn; • productName = productNameIn; • units = unitsIn; • } • public void setBrand(String brandIn) • { • brand = brandIn; • } • public String getBrand() • { • return brand; • }

  32. public void setProductName(String productNameIn) • { • productName = productNameIn; • } • public String getProductName() • { • return productName; • } • public void setUnits(String unitsIn) • { • units = unitsIn; • } • public String getUnits() • { • return units; • }

  33. public void setBrandToThisBrand(FoodV5 anotherFood) • { • String tempBrand = anotherFood.getBrand(); • setBrand(tempBrand); • } • public abstract double getUnitCost(); • }

  34. public class PackagedFoodV5 extends FoodV5 • { • private double size; • private double itemCost; • public PackagedFoodV5(String brandIn, String productNameIn, String unitsIn, • double sizeIn, double itemCostIn) • { • super(brandIn, productNameIn, unitsIn); • size = sizeIn; • itemCost = itemCostIn; • } • public void setSize(double sizeIn) • { • size = sizeIn; • } • public double getSize() • { • return size; • }

  35. public void setItemCost(double itemCostIn) • { • itemCost = itemCostIn; • } • public double getItemCost() • { • return itemCost; • } • public double getUnitCost() • { • return itemCost / size; • } • }

  36. public class BulkFoodV5 extends FoodV5 • { • private double unitCost; • public BulkFoodV5(String brandIn, String productNameIn, String unitsIn, double unitCostIn) • { • super(brandIn, productNameIn, unitsIn); • unitCost = unitCostIn; • } • public void setUnitCost(double unitCostIn) • { • unitCost = unitCostIn; • } • public double getUnitCost() • { • return unitCost; • } • public double findCost(double amount) • { • return amount * unitCost; • } • }

  37. 13.2 Polymorphism and Dynamic Binding

  38. This section basically repeats information given in Unit 12. • This section specifically uses the terminology polymorphism and dynamic binding in the explanations. • It also gives concrete examples using the class hierarchy developed in homework to show how polymorphism and dynamic binding apply in the specific case of parameter passing.

  39. 13.2.1 Superclass References to Subclass Objects are OK. This is Polymorphism • As pointed out in Unit 12, in Java it is syntactically possible to have a superclass reference to a subclass object. • Given any particular reference, it could refer to an object of its own class or any of its subclasses. • The type of the reference doesn’t tell the specific type of the object referred to.

  40. The term polymorphism is used to summarize the idea that a reference may refer to different kinds of objects. • This term comes from Greek roots meaning many and form.

  41. 13.2.2 Superclass References to Subclass Objects only have Access to Methods defined in the Superclass • Also, as pointed out in Unit 12, superclass references to subclass objects are distinctly limited. • A superclass reference cannot “know” about any instance variables or methods which are defined below it in the hierarchy. • If a method is not defined for the superclass, but is only defined in the subclass, it is not possible to call this method on a superclass reference to a subclass object.

  42. 13.2.3 If an Overridden Method is called on a Superclass Reference to a Subclass Object, the Version in the Subclass will be used. This is Dynamic Binding • Suppose each subclass in an inheritance hierarchy overrides a given superclass method. • Suppose also that the method is called on a superclass reference to a subclass object. • Calling the method on the superclass reference doesn't cause a problem because the method is defined in the superclass. • When the call is made the version of the method defined in the subclass will be used.

  43. The term dynamic binding means that the decision of which version of a method to use will be based on the actual type of the object referred to at run time, not the formal type of the reference as declared in the code. • It was pointed out previously that if the method were not overridden in the subclass, the call would still be OK. • The version of the method the subclass inherited from the superclass would be used. • The key point is that if it is overridden, the overridden version will be used.

  44. The overall conclusion is this: • If a method is called on a superclass reference to a subclass object, as long as the method is defined for the superclass, the call is OK. • Dynamic binding means that whatever version of the method is valid for that subclass, whether inherited or overridden, will be used.

  45. 13.2.4 Code Examples (Based on Previous Example, but Shortened with Ellipses) • This section repeats the code for the FoodV5, PackagedFoodV5, BulkFoodV5 class hierarchy, but with ellipses. • This code will then be used in reviewing concretely how polymorphism and dynamic binding work.

  46. public abstract class FoodV5 • { • private String brand; • private String productName; • private String units; • … • public void setBrand(String brandIn) • { • brand = brandIn; • } • public String getBrand() • { • return brand; • } • … • public void setBrandToThisBrand(FoodV5 anotherFood) • { • String tempBrand = anotherFood.getBrand(); • setBrand(tempBrand); • } • … • public abstract double getUnitCost(); • }

  47. public class PackagedFoodV5 extends FoodV5 • { • private double size; • private double itemCost; • … • public void setSize(double sizeIn) • { • size = sizeIn; • } • public double getSize() • { • return size; • } • … • public double getUnitCost() • { • return itemCost / size; • } • }

More Related