Presentation is loading. Please wait.

Presentation is loading. Please wait.

Object-Oriented Programming (Java), Unit 13

Similar presentations


Presentation on theme: "Object-Oriented Programming (Java), Unit 13"— 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 13.1 Abstraction in Class Design

4 Inheritance leads to two important questions.
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?

5 13.1.2 An Example of Needless Duplication—Implementation Too Low in the Hierarchy
The assignment for the previous unit specified a String variable named units in both the PackagedFoodV4 and BulkFoodV4 classes. This results in both classes containing code such as this: private String units; public void setUnits(String unitsIn) { units = unitsIn; } public String getUnits() return units;

6 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. Attributes and operations should be implemented at the highest level possible in an inheritance hierarchy.

7 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

8 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. 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.

9 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. It is desirable to be able to specify that such a method exist for all while having a separate implementation in each. Undesirable ways to accomplish would include the following: You could implement one of the subclass versions in the superclass, and the method would only have to be overridden in the other subclass. You could declare a method in the superclass with an empty body, containing no code. In either case the method as implemented in the superclass could not be correctly called on objects of the superclass.

10 It would appear in the Food class as follows:
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();

11 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 subclass. In this example, the Food class would have to be declared in the following way: public abstract class Food

12 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 call constructors and construct instances of an abstract class in a user program. However, an abstract class may contain constructors which are used by constructors of the subclasses. As noted earlier, construction at any level depends on cascading construction all the way up the inheritance hierarchy.

13 Example Code Here are the food classes rewritten using abstraction. FoodV5 is an abstract class. The getUnitCost() method is declared abstract in FoodV5. The implementations of the method in the subclasses differ. The getUnitCost() method for a packaged calculates the unitCost by dividing the itemCost by the size. The getUnitCost() method for a bulk food is a simple get method which returns the value of the unitCost instance variable.

14 Note that this is V5. Unit 12 ended with V3. The unit 12 assignment asked you to write V4. Note also, that in the previous unit, in the Food/TaxedFood hierarchy, the setMarkupToThisMarkup() method was given as an example In this unit, it is the Food/BulkFood/PackagedFood hierarchy under consideration. The FoodV4 class includes a setBrandToThisBrand() method—which you should have provided as part of the unit 12 assignment

15 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) public String getBrand() return brand;

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

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

18 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) public double getSize() return size;

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

20 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) public double getUnitCost() return unitCost; public double findCost(double amount) return amount * unitCost;

21 13.2 Polymorphism and Dynamic Binding

22 13. 2. 1 Superclass References to Subclass Objects are OK
Superclass References to Subclass Objects are OK. This is Polymorphism 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. The term polymorphism comes from Greek roots meaning many and form. This term is used to summarize the idea that a reference may refer to different kinds of objects.

23 Superclass references to subclass objects are distinctly limited.
Superclass References to Subclass Objects only have Access to Methods defined in the Superclass 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.

24 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 is used.

25 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 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 overridden or inherited, will be used.

26 13.2.4 Code Examples (Based on Previous Example, but Shortened with Ellipses)
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;

27 public void setBrandToThisBrand(FoodV5 anotherFood)
{ String tempBrand = anotherFood.getBrand(); setBrand(tempBrand); } public abstract double getUnitCost(); public class PackagedFoodV5 extends FoodV5 private double size; private double itemCost; public void setSize(double sizeIn) size = sizeIn; public double getSize() return size;

28 public double getUnitCost()
{ return itemCost / size; } public class BulkFoodV5 extends FoodV5 private double unitCost; public void setUnitCost(double unitCostIn) unitCost = unitCostIn; return unitCost;

29 13.2.5 Constructing Objects and Assigning References
Suppose you have a FoodV5 reference to a PackagedFoodV5 object, such as shown here: FoodV5 foodReference; PackagedFoodV5 packagedFoodReference = new PackagedFoodV5(…); foodReference = packagedFoodReference;

30 foodReference.setSize(…); …foodReference.getSize();
An Invalid Call: Calling a Method Defined Only in the Subclass on a Superclass Reference The following calls are not possible because the methods are not defined for the superclass: /* NO! NO! NO! */ foodReference.setSize(…); …foodReference.getSize(); The same would be true if FoodV5 were a superclass reference to a BulkFoodV5 object and the calls were to the methods setUnitCost() and getUnitCost().

31 13.2.7 The Method can be called if the Superclass Reference is Recovered
If the subclass reference is recovered, there is no problem calling a subclass method, as illustrated here: PackagedFoodV5 recovered = (PackagedFoodV5) foodReference; recovered.setSize(…);

32 Constructing Objects and Assigning References for a Call to a Method with a Reference as a Parameter Suppose you call the setBrandToThisBrand() method on a superclass reference to a subclass object: FoodV5 foodReference; PackagedFoodV5 packagedFoodReference = new PackagedFoodV5(…); foodReference = packagedFoodReference; foodReference.setBrandToThisBrand(…); The call on a superclass reference is allowed because this method is defined for the superclass. The method is not overridden in the subclass, so the version inherited from the superclass is used.

33 Automatic conversion occurs.
Automatic Converstion to a Superclass Reference Occurs when a Subclass Object is Passed as the Actual Parameter Here is a call to the setBrandToThisBrand() method with a subclass reference as the explicit parameter: PackagedFoodV5 packagedFoodReference = new PackagedFoodV5(…); …setBrandToThisBrand(packagedFoodReference); A subclass reference can be passed when the formal parameter is a superclass reference. Automatic conversion occurs.

34 Here is the code for the method again
Here is the code for the method again. The formal parameter, anotherFood, becomes a superclass reference to the explicit parameter, packagedFoodReference. public void setBrandToThisBrand(FoodV5 anotherFood) { String tempBrand = anotherFood.getBrand(); setBrand(tempBrand); }

35 13.2.10 Calling a Superclass Method on the Formal Parameter in the Body of the Method
Within the body of the method the explicit parameter is used in this one line of code: String tempBrand = anotherFood.getBrand(); This call is OK because the getBrand() method is defined in the superclass. The getBrand() method is not overridden in the subclass, and the call on the superclass reference to the subclass object makes use of the version of the method inherited from the superclass.

36 13.2.11 Calling an Overridden Method on the Formal Parameter in the Body of the Method
Consider a method setUnitCostToThisUnitCost(). It obtains a unitCost from the explicit parameter and assigns it to the implicit parameter. The BulkFoodV5 class has an instance variable unitCost which can be set, so the method could be called on such an object. The unitCost of the PackagedFoodV5 class is calculated. The class doesn't have a unitCost instance variable, so the method could not be called on such an object. Because the method does not apply to packaged food objects, it could only be implemented in the BulkFoodV5 class.

37 The explicit parameter of the method could be either a PackagedFoodV5 or a BulkFoodV5 reference because a unitCost can be obtained from either. The formal parameter is declared to be a superclass reference, BulkFoodV5, to allow for actual parameters of either subclass. Here is the code: public void setUnitCostToThisUnitCost(FoodV5 anotherFood) { double tempUnitCost = anotherFood.getUnitCost(); setUnitCost(tempUnitCost); }

38 Dynamic Binding Means that the Appropriate Version of the Method is Called on the Formal Parameter, which is a Superclass Reference The key element of the example is the following line of code in the body of the setUnitCostToThisUnitCost() method: double tempUnitCost = anotherFood.getUnitCost(); When a call is made to the setUnitCostToThisUnitCost() method, a subclass object will be accepted as the explicit parameter. The parameter is automatically converted to a superclass reference. The getUnitCost() method exists in the superclass, so it can be called on this superclass reference.

39 The getUnitCost() method is declared abstract in the FoodV5 class, and different implementations exist in each of the subclasses. If the formal parameter, the superclass reference anotherFood, refers to a PackagedFoodV5 object, then the getUnitCost() method found in the PackagedFoodV5 class will be used. If the formal parameter, the superclass reference anotherFood, refers to a BulkFoodV5 object, then the getUnitCost() method found in the BulkFoodV5 class will be used. The phrase dynamic binding means that the system determines the type of the actual parameter referred to by the formal parameter at run time and uses the corresponding version of getUnitCost().

40 13.2.13 Recapitulation of Polymorphism and Dynamic Binding
Methods that are defined for the superclass can be called on a superclass reference. A superclass reference does not have access to methods that are only defined in the subclass. Polymorphism means that superclass references to subclass objects are possible. Dynamic binding means that at run time the system determines the actual object type of a superclass reference. If a method is called on a superclass reference, if the method has been overridden in the subclass, the system will use the version of the method existing in the subclass, not the version in the superclass. If the method has not been overridden, the inherited version will be used in any case. It is possible to pass subclass objects as parameters to methods where the formal, explicit parameter is of the superclass type. When this is done, automatic conversion occurs, and the formal parameter becomes a superclass reference. The rules for dynamic binding apply to these superclass references.

41 13.3 Multiple Inheritance and Interfaces

42 13.3.1 What is Multiple Inheritance?
The following diagram illustrates multiple inheritance. The idea is that the Cow class has two parent classes instead of one.

43

44 13. 3. 2 Java doesn't Support Multiple Inheritance
Java doesn't Support Multiple Inheritance. It has Interfaces instead Java does not support multiple inheritance. A class can only have one immediate parent. Syntactically, it is only possible for a class to extend one other class.

45 Instead of multiple inheritance, Java has interfaces.
An interface contains no instance variables. An interface is a specification of a set of methods. An interface contains no implementations for the specified methods. (In this sense it is kind of like a completely abstract class.) The methods in the interface definition are not given an access modifier. They are public by default. (Declaring them public is not a fatal error.)

46 A class can implement an interface.
Implementing the interface means implementing all of the methods listed in the interface specification. The implementations of the methods have to be declared public. Implementing the interface also means supplying all of the instance variables that might be needed to support these methods.

47 What is an Interface? The following diagram illustrates an interface.

48

49 The hierarchy should still support both packaged and bulk foods.
The hierarchy should still support both taxed and untaxed food items of both kinds. Taxation should be handled in the same way for both packaged and bulk foods. The changes required by implementing the interface cause the taxed classes to extend the untaxed ones.

50 Defining an Interface Let the Taxable interface be defined as shown below. public interface Taxable { void setTaxRate(double TaxRateIn); double getTaxRate(); double findTaxValuePerUnit(); }

51 Although the variable is not shown, any class that implements this interface will have to have a double instance variable named taxRate. It has to have these two methods: setTaxRate() and getTaxRate(). It has to have a method findTaxValuePerUnit(). Because unitCost is an instance variable in BulkFoodV5 but calculated in PackagedFoodV5, the implementation of findTaxValuePerUnit() will differ in the two implementing classes.

52 An interface is stored in a file with the same name as the interface.
An interface definition is stored in a .java file (like a class). The interface is declared public. However, an interface is not a class. There can be no instances of it. An interface can have no "subclasses".

53 13.3.5 An Example of a Class Implementing an Interface
public class TaxedPackagedFoodV5 extends PackagedFoodV5 implements Taxable { private double taxRate; public TaxedPackagedFoodV5(String brandIn, String productNameIn, String unitsIn, double sizeIn, double itemCostIn, double taxRateIn) super(brandIn, productNameIn, unitsIn, sizeIn, itemCostIn); taxRate = taxRateIn; }

54 public void setTaxRate(double taxRateIn)
{ taxRate = taxRateIn; } public double getTaxRate() return taxRate; public double findTaxValuePerUnit() return (getItemCost() / getSize()) * taxRate;

55 This class first extends its parent class and then implements the interface.
The needed instance variable, taxRate, is declared as part of the class definition, and it is used in the constructor. Get and set methods are provided for the instance variable. An appropriate findTaxValuePerUnit() method is implemented for this class.

56 13.3.6 Summary of the Interface Idea
You inherit nothing from an interface, neither instance variables nor methods. If you choose to implement an interface, what you get is a set of requirements that have to be met. Certain methods have to be implemented, and anything else needed in the class in order to support these methods, such as instance variables, also has to be supplied. Interfaces are as close as Java comes to supporting the concept of multiple inheritance.

57 13.4 An Example from the Java API: The Point Classes

58 13.4.1 Example Excerpts from the Java API Documentation for the Point Classes
These classes illustrate inheritance, abstraction, and interfaces. java.lang Class Object java.lang.Object public class Object Class Object is the root of the class hierarchy. Every class has Object as a superclass. All objects, including arrays, implement the methods of this class.

59 java.awt.geom Class Point2D
java.lang.Object java.awt.geom.Point2D All Implemented Interfaces: Cloneable Direct Known Subclasses: Point, Point2D.Double, Point2D.Float public abstract class Point2D extends Object implements Cloneable The Point2D class defines a point representing a location in (x, y) coordinate space. This class is only the abstract superclass for all objects that store a 2D coordinate. The actual storage representation of the coordinates is left to the subclass.

60 Nested Class Summary static classPoint2D.Double The Double class defines a point specified in double precision. static classPoint2D.Float The Float class defines a point specified in float precision. Constructor Summary protected Point2D() This is an abstract class that cannot be instantiated directly.

61 java.awt.geom Class Point2D.Double
java.lang.Object java.awt.geom.Point2D java.awt.geom.Point2D.Double All Implemented Interfaces: Cloneable Enclosing class: Point2D public static class Point2D.Double extends Point2D The Double class defines a point specified in double precision.

62 Nested Class Summary  Nested classes/interfaces inherited from class java.awt.geom.Point2D Point2D.Double, Point2D.Float  Field Summary double x The X coordinate of this Point2D. double y The Y coordinate of this Point2D.  Constructor Summary Point2D.Double() Constructs and initializes a Point2D with coordinates (0, 0). Point2D.Double(double x, double y) Constructs and initializes a Point2D with the specified coordinates.

63 Method Summary double getX() Returns the X coordinate of this Point2D in double precision. double getY() Returns the Y coordinate of this Point2D in double precision. void setLocation(double x, double y) Sets the location of this Point2D to the specified double coordinates. String toString() Returns a String that represents the value of this Point2D.  Methods inherited from class java.awt.geom.Point2D clone, distance, distance, distance, distanceSq, distanceSq, distanceSq, equals, hashCode, setLocation  Methods inherited from class java.lang.Object finalize, getClass, notify, notifyAll, wait, wait, wait

64 13.4.2 How the Point Classes Exhibit Inheritance, Abstraction, and Interfaces
Reading the API documentation it is possible to see the following: Object is the parent class of Point2D, which is the parent class of Point, Point2D.Double, and Point2D.Float. Point2D is an abstract class and there can be no instances of it. The subclasses implement various interfaces.

65 13.4.3 The Treatment of Instance Variables in the Point Classes
The Point2D class does not have any instance variables. The declaration of the instance variables for the coordinates of a point, x and y, are in the subclasses. The x and y coordinates of the Point class are typed integer. The x and y coordinates of the Point2D.Double and Point2D.Float classes are typed double and float, respectively.

66 It is not syntactically possible to declare "abstract" instance variables x and y in the superclass, Point2D. As noted earlier, it is not possible to "override" instance variables. Although syntactically possible, it would be incorrect to declare instance variables x and y of a given type in Point2D and then declare instance variables with the same names in the subclasses. In order to support three different kinds of points which differ only in the types of their instance variables, it is necessary to put the declarations of the instance variables in each of the subclasses. Because the meaning of the x and y coordinates is not changed by their numeric types, it is logically acceptable to have instance variables with the same names in the subclasses.

67 13.4.4 An Inherited Method Among the Point Classes
Methods which use the coordinate instance variables are defined in the superclass, Point2D, and inherited by the subclasses. For example: abstract  double getX() Returns the X coordinate of this Point2D in double precision. The abstract superclass, Point2D, has this similarity with an interface: It defines methods which use the expected instance variables, but it does not declare those variables for the subclasses to inherit.

68 13.4.5 Nested or Inner Classes, as Illustrated by the Point Classes
The classes Point2D.Double and Point2D.Float are listed as nested classes of Point2D. They may also be referred to as inner classes. This means that the definitions of both Point2D.Double and Point2D.Float are completely contained within the braces of the code for the Point2D class. Inner classes always have to be referred to by their compound names using dot notation such as Point2D.Double. When importing inner classes, it is sufficient to specify the name of the outer class in the import statement. The inner class is imported as a consequence.

69 Being a subclass and being an inner class are independent of each other.
The subclass Point is not an inner class of Point2D while the other two subclasses are. The differing implementations of the three subclasses came about for historical reasons. The fact that the code for an inner class is completely contained within the code for the outer class will have significant implications in the future. It has no particular importance for the point classes.

70 The End


Download ppt "Object-Oriented Programming (Java), Unit 13"

Similar presentations


Ads by Google