Java Unit 11 Inheritance I References to Classes






















- Slides: 22

Java Unit 11: Inheritance I References to Classes and Subclasses in Programs and methods

Write Superclass before Subclass �The use and testing of subclasses does not differ greatly from the use and testing of any programmer written class. �When creating a hierarchy of classes, you have to work your way from the top down. �Subclasses can only be compiled if their superclasses exist. A test program at any level includes code that makes use of all constructors and methods in the class to make sure that they work correctly.

Test Superclass before Subclass �Before starting to write a subclass, its superclass should be tested. �If this is not done it is possible to encounter problems when writing and testing a subclass that are in fact caused by errors in the superclass.

Assigning a Subclass Object to a Superclass Reference �When working with classes in a hierarchy, object references take on a new aspect. �A reference to a subclass object can always be assigned to a reference that is declared to be of the type of any of the subclass’s superclasses. �This stems from the basic idea of inheritance, that instances of classes lower down in the hierarchy are a kind of the classes higher in the hierarchy. In the same way that human beings are members of the animal kingdom, a taxed food is a kind of food.

Assigning a Subclass Object to a Superclass Reference �Syntactically, this idea can be illustrated as follows: �Food. V 2 my. Food; Taxed. Food. V 2 my. Taxed. Food = new Taxed. Food. V 2(“bread”, 0. 50, 0. 05, 0. 07); my. Food = my. Taxed. Food;

Assigning a Subclass Object to a Superclass Reference �A subclass object can be assigned to a superclass reference without any special syntax. �This is both logically and syntactically OK. �The object specifically is a taxed food item, but that does not keep it from being a food item generally, and an assignment such as this is permitted without casting.

Assigning a Subclass Object to a Superclass Reference �It is important to note, however, that as soon as the reference to an object is a superclass reference, on that reference it is only possible to call the methods defined in the superclass or methods inherited by the superclass. �It is not possible to call methods on a superclass reference if the methods are only defined in the subclass.

Casting a Superclass Reference back into a Subclass Object �While it is possible to make an assignment from a subclass reference to a superclass reference without casting, going in the other direction is not always possible. Casting can be used in order to recover the actual class that a superclass reference belongs to.

Casting a Superclass Reference back into a Subclass Object Food. V 2 my. Food; Taxed. Food. V 2 my. Taxed. Food = new Taxed. Food 2(“bread”, 0. 50, 0. 05, 0. 07); my. Food = my. Taxed. Food; Taxed. Food. V 2 new. Taxed. Food = (Taxed. Food. V 2) my. Food;

Casting a Superclass Reference back into a Subclass Object �In the final line, on the right, my. Food is a superclass reference to a subclass object. The system internally knows what kind of object it is a reference to, and it is possible to cast that reference back to the original type and recover it in a new reference of that type.

Can’t cast to types outside the hierarchy �This type of casting will not work if the type on the left is not the same type as the actual object on the right. Here is a gross example of something that is simply NOT possible: �//NOOOOO! Ellipse 2 D. Double my. Ellipse = new Ellipse 2 D. Double(10, 20, 30, 40); Taxed. Food. V 2 my. Taxed. Food = (Taxed. Food. V 2) my. Ellipse; �It should be obvious that it is illogical to try to cast an ellipse to a food.

Can’t cast to types outside the hierarchy Ketchup Food Waffles Product Toothpaste Non. Food Cat Toy

Can’t cast superclasses to subclasses �The following is equally impossible: �/* NO! NO! */ Food. V 2 my. Food = new Food. V 2(“cheese”, 1. 25, . 06); Taxed. Food. V 2 my. Taxed. Food = (Taxed. Food. V 2) my. Food; �Even though my. Food and my. Taxed. Food are in the same inheritance hierarchy, in this example my. Food never was a taxed food. �It is impossible to use casting to recover a kind of reference that never existed. �As a general rule, it is not possible to cast superclasses to subclasses, except in those cases where you are recovering an original reference type.

‘instanceof’ Keyword �This introduces another keyword that allows you to test whether a reference belongs to a particular class before trying to cast it. �The keyword instanceof functions as an operator that returns a boolean value. It compares the actual type of a reference to a given class.

‘instanceof’ Keyword �The fragment below illustrates its use to permit a valid cast and prevent a mistaken one: �if (my. Food instanceof Taxed. Food. V 2) { Taxed. Food. V 2 new. Taxed. Food = (Taxed. Food. V 2) my. Food; }

Passing Object References as Parameters �The question of reference type becomes critical when passing object references as parameters to methods in an inheritance hierarchy. �A subclass object can always be given a superclass reference. �What follows from this is the idea that when a superclass reference is specified, it is permissible to use a subclass object or reference in its place.

Passing Object References as Parameters �Here is a new method for use in the food class. �Let this be the next modification of the example, so that the class names now include V 3 at the end. �It is possible to set the markup of one food item to the markup already stored in another. This is accomplished by passing the other object as a parameter to the method. �The parameter is typed Food. V 3, the same as the (super) class the method appears in.

Passing Object References as Parameters public void set. Markupt. To. This. Markup(Food. V 3 another. Food) { double temp. Markup = another. Food. get. Markup(); set. Markup(temp. Markup); }

Passing Object References as Parameters �Now suppose the following code exists in a program that uses this set of classes: � Taxed. Food. V 3 my. Taxed. Food = new Taxed. Food. V 3(“bread”, 0. 50, 0. 05, 0. 07); Taxed. Food. V 3 your. Taxed. Food = new Taxed. Food. V 3(“milk”, 0. 75, 0. 08, 0. 07); my. Taxed. Food. set. Markup. To. This. Markup(your. Taxed. Food);

Passing Object References as Parameters �Is the call in the third line correct? The method is inherited by the subclass, so making the call on my. Taxed. Food is possible. �The apparent problem is that the type of the explicit parameter, your. Taxed. Food, is Taxed. Food. V 3, but in the method definition the expected parameter is typed Food. V 3. �In other situations where the actual parameter type did not agree with the formal parameter type, the compiler detected an error.

Passing Object References as Parameters �However, in this case there is not a problem. The system knows that Taxed. Food. V 3 is a subclass of Food. V 3, and it does automatic type conversion. �When the actual parameter, a taxed food object, is passed, that reference is automatically converted to a Food. V 3 reference. �This is possible because a superclass reference to a subclass object is allowed.

New Food classes �The changes made to Food. V 3 and Taxed. Food. V 3 will be found on our website.