910 likes | 1.09k Views
Object-Oriented Programming (Java), Unit 12. Kirk Scott. Inheritance, Part I. 12.1 What is Inheritance? 12.2 Writing the Code for Subclasses 12.3 Access to Instance Variables and Overriding Methods. 12.4 A Note on the Meaning of Inheritance
E N D
Object-Oriented Programming (Java), Unit 12 Kirk Scott
Inheritance, Part I • 12.1 What is Inheritance? • 12.2 Writing the Code for Subclasses • 12.3 Access to Instance Variables and Overriding Methods
12.4 A Note on the Meaning of Inheritance • 12.5 The Key Word super, Methods, and Construction • 12.6 References to Classes and Subclasses in Programs and Methods
12.1.1 Superclass/Subclass, Parent Class/Child Class Terminology • The class at the top of an inheritance hierarchy has nothing above it. • Any other class has exactly one class immediately above it in the hierarchy. • Any given class may have more than one class above it, at different levels in the hierarchy.
The class immediately above a given class may be called the parent class or superclass. • All classes above it are known generally as superclasses.
A class can have more than one class immediately below it. • Below that may be others, and so on. • A class immediately below a given class may be called a child class or a subclass. • All classes below it are known generally as subclasses.
12.1.2 "Is-a" or "Is-a-Kind-of" Relationships • The relationship between items in an inheritance hierarchy can be described as an “is a” or “is a kind of” relationship. • Any class that appears lower down in the hierarchy must be an example of, or a more specific kind of, whatever classes appear above it in the hierarchy.
In the field of biology the classification of all living things is based on this idea. This is referred to as taxonomy. • The taxonomy of human beings is shown below. • This illustrates one relatively complete branch of an inheritance hierarchy.
Kingdom: Animalia • Phylum: Chordata • Class: Mammalia • Order: Primates • Family: Hominidae • Genus: Homo • Species: sapiens
12.1.3 Inheritance Hierarchies are Tree-Like • The UML-like diagram below illustrates the tree-like nature of inheritance hierarchies. • This is described as a tree, although it is customary to represent it “upside down”, with the root at the top.
12.1.4 In Java the Root Class and the Default Parent Class is Named Object • In Java the single class at the top of the hierarchy, or the root of the tree, is a class named Object. • All system supplied classes are arranged in a hierarchy beneath this class. • When a programmer writes classes and a parent class is not specified, such classes become children, or immediate subclasses, of the Object class.
There is a syntax allowing programmers to specifically make one class a subclass of another. • It will be covered later.
12.1.5 Subclasses Inherit Instance Variables and Methods, but Not Constructors • Classes in the hierarchy are related by inheritance. • Any class that has classes above it in the hierarchy inherits characteristics of those superclasses. • These characteristics include instance variables and methods. • Constructors are not inherited.
It is natural, and possible, for subclasses to add instance variables and methods which do not exist in the superclasses. • This is the main way in which subclasses distinguish themselves from their superclasses. • There may also be situations where it is undesirable to inherit characteristics. • There is syntax which thwarts inheritance. • It will be covered later.
12.1.6 Do Not Confuse Individual Inheritance with Class Inheritance • Different uses of the term inheritance can potentially lead to confusion. • Inheritance can be used to refer to the characteristics an individual child receives from a particular parent, for example. • This is not the sense of inheritance as it's used here.
The taxonomic example shows inheritance among categories, not individuals. • This does illustrate the sense of inheritance as it's used here. • For example, the genus Homo is the parent class of the species sapiens in the hierarchy. • Homo doesn't represent some individual parent and sapiens doesn't represent some individual child.
12.1.7 The Hierarchy Containing Rectangle2D in the Java API Documentation • The Java API documentation for the class Rectangle2D shows an inheritance hierarchy. java.lang.Object java.awt.geom.RectangularShape java.awt.geom.Rectangle2D • Object is the parent class of RectangularShape and RectangularShape is the parent class of Rectangle2D.
The class names are fully qualified using dot notation to show which packages they are in, java.lang or java.awt.geom. • Package membership does not indicate inheritance relationships.
12.2.1 The Food Class Example • Consider a class, FoodV1, which represents kinds of food items from the point of view of the store where they are sold. • Code for this class is given on the next overhead. • The instance variables for this class are name, wholesaleCost, and markup. • By default, this class is a subclass of the Object class.
public class FoodV1 • { • private String name; • private double wholesaleCost; • private double markup; • public FoodV1() • { • } • public void setName(String nameIn) • { • name = nameIn; • } • public String getName() • { • return name; • }
public void setWholesaleCost(double wholesaleCostIn) • { • wholesaleCost = wholesaleCostIn; • } • public double getWholesaleCost() • { • return wholesaleCost; • } • public void setMarkup(double markupIn) • { • markup = markupIn; • } • public double getMarkup() • { • return markup; • } • public double getPrice() • { • return (wholesaleCost + wholesaleCost * markup); • } • }
12.2.2 Creating Subclasses • It is possible to create a class, TaxedFoodV1, which is a subclass of the FoodV1 class. • Here is a UML diagram showing the inheritance relationship between these classes and the Object class:
12.2.3 The Keyword extends • The keyword for specifying a subclass is extends. • Syntactically, the child specifies its one parent; the parent doesn’t specify its potentially many children. • Here is the code for the TaxedFoodV1, a child class of FoodV1:
public class TaxedFoodV1 extends FoodV1 • { • private double taxRate; • public TaxedFoodV1() • { • } • public void setTaxRate(double taxRateIn) • { • taxRate = taxRateIn; • } • public double getTaxRate() • { • return taxRate; • } • }
12.2.4 Constructors • There is nothing unusual about the TaxedFoodV1 class regarding construction • It has a default constructor and an instance of the class can be constructed as usual: • TaxedFoodV1 myTaxedFood= new TaxedFoodV1();
12.2.5 The Inheritance of Instance Variables • The TaxedFoodV1 class has one instance variable of its own, taxRate. • The class also inherits all of the instance variables of the class FoodV1. • An object of this class (e.g., myTaxedFood)has all of the following instance variables: • name inherited • wholesaleCost inherited • markup inherited • taxRate not inherited
12.2.6 The Inheritance of Methods • The TaxedFoodV1 class has get and set methods for the instance variable taxRate defined in it. • It also inherits all of the methods (which were declared public) of the class FoodV1. • After myTaxedFoodV1 has been constructed, calls to the inherited methods can be freely made on it.
TaxedFoodV1 myTaxedFood = new TaxedFoodV1(); • myTaxedFood.setname(“Peas”); • double retrievedCost = myTaxedFood.getWholesaleCost(); • double retrievedPrice = myTaxedFood.getPrice();
12.3.1 Inherited Instance Variables Are Not Directly Accessible • Both (private) instance variables and (public) methods are inherited. • Inherited instance variables declared private in the superclass (as they should be) are not directly accessible in the subclass. • When using an instance of a subclass, it is possible to work with the object’s inherited instance variables by using the inherited get and set methods.
12.3.2 Thwarting Inheritance by Overriding Methods • As subclasses become more specific, it is possible that an inherited method does not completely accomplish what needs to be accomplished. • It is syntactically possible for a subclass to have a method with the same name as a method in one of its superclasses, and with the same parameter list.
This is referred to as overriding the inherited method. • If a call is made on an object of the subclass using that method name, the version of the method defined in the subclass is used, not the version in the superclass. • Inheritance is thwarted by overriding.
12.3.3 Do Not Confuse Overriding with Overloading • It is also possible to write a method in a subclass with the same name as a method in one of its superclasses, but with a different parameter list. • In this case you have not overridden the inherited method. • This is overloading. • The two should not be confused.
Overloading also applies in the simpler case of a single class • A given class may have two methods with the same name but a different parameter list • The system distinguishes between them based on the parameter list • Having the same name, the two methods should accomplish approximately the same thing, but on the basis of different input parameters
12.3.4 An Example Illustrating Overriding • The method getPrice() as defined in the class FoodV1 calculates a checkout price based on the wholesale cost of the item and the markup charged by the store. • The checkout price for a taxed food item should include the tax on that item. • This shows how the method might be correctly implemented in the TaxedFoodV1 class:
public double getPrice() • { • double retrievedCost; • double retrievedMarkup; • double costPlusMarkup; • double price; • retrievedCost = getWholesaleCost(); • retrievedMarkup = getMarkup(); • costPlusMarkup = retrievedCost + retrievedCost * retrievedMarkup; • price = costPlusMarkup + costPlusMarkup * taxRate; • return price; • }
12.3.5 Lack of Direct Access • There is no direct access to the inherited instance variables. • The code above has to use the get methods to access the inherited variables. • retrievedCost = getWholesaleCost(); • retrievedMarkup = getMarkup();
12.3.6 Remembering the Implicit Parameter • The previous example code illustrated method calls “hanging in space” • In other words, the standard way of calling a method is object.method() • The calls above show no object on which the calls are being made • In this case, the calls are being made on the implicit parameter
The calls could be written using the implicit parameter. • retrievedCost= this.getWholesaleCost(); • retrievedMarkup = this.getMarkup(); • The retrieved values come from whatever object the getPrice()method, which contains these calls, was called on.
12.3.7 Review of Lack of Direct Access and Overriding • The implicit parameter of the call to getPrice(), a TaxedFoodV1 object, would have wholesaleCost and markup variables by inheritance. • Inherited variables can only be accessed through inherited get methods. • Sometimes it is desirable to write an implementation of a specific method in a subclass which differs from the implementation that it would otherwise inherit. • This is overriding.
12.3.8 Using the Overridden Method • Suppose that the following objects were constructed: • FoodV1 myFood= new FoodV1(); • TaxedFoodV1 yourFood= new TaxedFoodV1(); • Suppose also that set methods had been called so that their price, markup, and taxRate variables had been set.
Now consider the following two calls: • double x = myFood.getPrice(); • double y = yourFood.getPrice(); • The two calls to getPrice() in the lines of code above are to two different versions of the method. • Which version of the method is called depends on which kind of object it is called on, an instance of FoodV1 or an instance of TaxedFoodV1.
12.3.9 Inheritance from Multiple Levels • Consider the following general inheritance hierarchy:
If methodX() is implemented in the Top class and not implemented in the other two classes, then it is inherited by both Middle and Bottom. • If methodX() is implemented in Middle, then it does not exist for objects of the Topclass; it is inherited by the Bottom class. • If methodX() is implemented in the Top class, overridden in the Middle class, and inherited by the Bottom class, the version nearest to the Bottom class as you move upwards through the hierarchy is inherited; this is the version implemented in the Middle class.
12.3.10 Instance Variables Can't Be Overridden • It is not possible to override instance variables. • It is syntactically possible to declare instance variables in subclasses with the same name as instance variables in its superclasses (and with different types). • It is unfortunate that this is syntactically possible, because from a practical point of view it is a big mistake to do something like this. • It will be extremely difficult to unravel the meaning of the code.
The idea of overriding instance variables is also a problem conceptually. • Instance variables should represent inherent characteristics of classes. • If it seems desirable to change an instance variable in a subclass, that’s a sign that that class is in the wrong place in the inheritance hierarchy.