Presentation is loading. Please wait.

Presentation is loading. Please wait.

Class Inheritance Part II: Overriding and Polymorphism Corresponds with Chapter 10.

Similar presentations


Presentation on theme: "Class Inheritance Part II: Overriding and Polymorphism Corresponds with Chapter 10."— Presentation transcript:

1 Class Inheritance Part II: Overriding and Polymorphism Corresponds with Chapter 10

2 The Object Class Object is the root class of all classes in Java Object is the root class of all classes in Java All other classes are descendents of Object All other classes are descendents of Object Object is part of the java.lang package Object is part of the java.lang package Useful Object methods: Useful Object methods: equals-- tests for equality of value of two different objects equals-- tests for equality of value of two different objects clone – instantiates a copy of an object (only if it implements the Cloneable inteface). clone – instantiates a copy of an object (only if it implements the Cloneable inteface). getClass – returns the class to which an object belongs getClass – returns the class to which an object belongs toString – returns a string of that object (by default, its class name and id, but this can be overridden). toString – returns a string of that object (by default, its class name and id, but this can be overridden).

3 What is Polymorphism? Polymorphism = the ability of object oriented programs to generate different behavior with identical method calls. Polymorphism = the ability of object oriented programs to generate different behavior with identical method calls. Dynamic Binding = run-time decision on which version of the method will execute (based on the instance’s class type) Dynamic Binding = run-time decision on which version of the method will execute (based on the instance’s class type) Note that reference variables can point to instances of the reference’s class OR to instances of the reference’s subclasses. Note that reference variables can point to instances of the reference’s class OR to instances of the reference’s subclasses. When calling an instance method through a reference variable, the version of the method that actually executes is NOT based on the type (class) of the reference variable. It is based on the type (class) of the instance that the reference variable points to. When calling an instance method through a reference variable, the version of the method that actually executes is NOT based on the type (class) of the reference variable. It is based on the type (class) of the instance that the reference variable points to.

4 Implementing Polymorphism in Java Override methods in subclasses Override methods in subclasses Declare reference variables of the superclass type Declare reference variables of the superclass type Instantiate superclass-type reference variables with superclass instances OR Instantiate superclass-type reference variables with superclass instances OR Instantiate superclass-type reference variables with subclass instances Instantiate superclass-type reference variables with subclass instances Perform method calls of overridden methods via the superclass variables Perform method calls of overridden methods via the superclass variables If the superclass-type reference variable is pointing to a superclass instance, it is the superclass version of the overridden method that will be calledBUT If the superclass-type reference variable is pointing to a superclass instance, it is the superclass version of the overridden method that will be calledBUT If the superclass-type reference variable is pointing to a subclass instance, it is the subclass version of the overridden method that will be called If the superclass-type reference variable is pointing to a subclass instance, it is the subclass version of the overridden method that will be called Therefore, it is the instance’s class (NOT the reference’s class) that determines which version of the method is called. Therefore, it is the instance’s class (NOT the reference’s class) that determines which version of the method is called. Therefore, it may not be known at compile time which version is called…it is not until instantiation (at run-time) that this is known: Therefore, it may not be known at compile time which version is called…it is not until instantiation (at run-time) that this is known:  This is dynamic binding.  This is dynamic binding.

5 Overriding the Object class’s toString method Even though there is not extends keyword, Circle is a subclass of Object. Object is the root of ALL classes in Java

6 Overriding the Circle class’s toString method In this example we are NOT overriding the Circle class’s findArea method

7 Overriding the Circle class’s toString method Overriding the Circle class’s findArea method If no explicit super call is made in the subclass constructor, the superclass’s default constructor is invoked by default.

8 UML Diagram of Classes used in this Example Super class subclasses All attributes and operations are inherited by subclasses findArea at Sphere level overrides findArea of Circle no findArea at Cylinder level, therefore use the inherited findArea of Circle Each subclass has its own version of findVolume, which is not at the superclass level. Object is the root of all classes We are overriding the Object class’s toString in all the descendent classes

9 An example of using polymorphism (application class)

10

11 Note: the array is of type Circle (the superclass)  thus the elements can point to ANY kind of Circle object (including instances of subclasses). But the instances that are created may be of any descendent class of Circle. Here, we see that, depending on the user’s choice, each element of the Circle array may be pointing at a Circle object, a Cylinder object, or a Sphere object. This will not be known until the program executes and the user makes a choice.

12 An example of using polymorphism (application class) Yet, a call to the method is being done via a Circle reference. How do we know which version of the method to call? This reference could point to instances of different types! Answer – we know this because of dynamic binding…the version that is called will be determined by the instance that is pointed at.

13 Dynamic binding is possible because the Java Virtual Machine knows the specific class of all objects. You can see the class of a particular instance by using the getClass() method of the Object class. An example of using polymorphism (application class)

14 If an object is referred to in a String context, its toString method is invoked Since the three classes have their own toString methods, the version invoked depends on the instance that is referenced…polymorphism and dynamic binding in action again! An example of using polymorphism (application class)

15 The instanceof keyword is another useful way of determining the class of an object. It returns a boolean value indicating whether an object is an instance of a specified class. An example of using polymorphism (application class)

16 If attempting to call a subclass method (not declared at the superclass) via a superclass reference, you will get a syntax error. Thus, you will need to cast the reference as a subclass reference before making the call. In this case, findVolume is declared for Cylinder and Sphere, but not for CircleWithAccessors, so casting is necessary. Note that the instanceof operator enabled me to see whether a call to findVolume was appropriate. An example of using polymorphism (application class)

17 What is Type Casting? Treating a variable as if it is a different data type than what it was declared as Treating a variable as if it is a different data type than what it was declared as Why? Because sometimes you need to perform operations on the object that are not available for the declared variable type Why? Because sometimes you need to perform operations on the object that are not available for the declared variable type Let’s consider the circles array and the necessity to call findVolume….. Let’s consider the circles array and the necessity to call findVolume…..

18 Why we need to cast… The circles array is declared: The circles array is declared: Circle [] circles Circle [] circles In order to call findVolume() on an instance pointed at by an element of the circles array, we would do this: In order to call findVolume() on an instance pointed at by an element of the circles array, we would do this: circles[i].findVolume() circles[i].findVolume() But, there is no findVolume method of the Circle class! If we did the above line, it would result in a syntax error. As far as the compiler is concerned, we are attempting to call a method on a Circle instance. But, there is no findVolume method of the Circle class! If we did the above line, it would result in a syntax error. As far as the compiler is concerned, we are attempting to call a method on a Circle instance. Solution: use type casting

19 How to Cast Precede the variable identifier with the name of the data type you want to cast it as in parentheses: Precede the variable identifier with the name of the data type you want to cast it as in parentheses: (Cylinder)circles[i] (Cylinder)circles[i] The above line treats circles[i] as a reference to a Cylinder object instead of as a reference to a CircleWithAccessors object. The text (Cylinder) is called a cast operator. The above line treats circles[i] as a reference to a Cylinder object instead of as a reference to a CircleWithAccessors object. The text (Cylinder) is called a cast operator. Note: operator precedence rules dictate that the dot operator takes place before the cast operator…therefore, in order to cast before attempting the member access, you need to use parentheses to override normal precedence: Note: operator precedence rules dictate that the dot operator takes place before the cast operator…therefore, in order to cast before attempting the member access, you need to use parentheses to override normal precedence: ((Cylinder)circles[i]).findVolume(); ((Cylinder)circles[i]).findVolume(); Cast comes first because of parentheses Dot operator is then applied to a Cylinder reference instead of a Circle reference

20 Heap Frame Stack main’s frame args circles 012 i Let’s see what happens when we create an array of superclass references that point to subclass instances

21 Heap Frame Stack main’s frame args circles 012 Circle object radius 5.0 Cylinder object radius 5.0 length 2.0 Sphere object radius 5.0 i Assume the first time user selects circle, 2 nd time user select cylinder, and 3 rd time user selects Sphere…. Therefore, the array has Circle pointers, but each object could be any descendent of Circle.

22 Heap Frame Stack main’s frame args circles 012 Circle object radius 5.0 Cylinder object radius 5.0 length 2.0 Sphere object radius 5.0 i 0 Circle findArea frame this The first instance is a Circle object. Dynamic binding at work!

23 Heap Frame Stack main’s frame args circles 012 Circle object radius 5.0 Cylinder object radius 5.0 length 2.0 Sphere object radius 5.0 i 1 The 2 nd instance is a Cylinder object, which does not have its own findArea method, so the superclass’s version is invoked. Circle findArea frame this Dynamic binding at work!

24 Heap Frame Stack main’s frame args circles 012 Circle object radius 5.0 Cylinder object radius 5.0 length 2.0 Sphere object radius 5.0 i 0 Sphere findArea frame this The 3 rd instance is a Sphere object, which has its own findArea method, so the overriding method is called. Dynamic binding at work!

25 Other Concepts to Consider Abstract class Abstract class A class that contains some non-implemented (abstract) methods… A class that contains some non-implemented (abstract) methods… Methods that contain a signature but no method body Methods that contain a signature but no method body Abstract classes cannot be instantiated, but can be superclasses of instantiable subclasses. Abstract classes cannot be instantiated, but can be superclasses of instantiable subclasses. Abstract classes can have variables Abstract classes can have variables Declared using the abstract keyword Declared using the abstract keyword Interface Interface A “class” that contains ONLY non-implemented methods A “class” that contains ONLY non-implemented methods Declared using the interface keyword. Declared using the interface keyword. Inheritance done via the implements keyword instead of extends. Inheritance done via the implements keyword instead of extends. Interfaces cannot be instantiated, but can be “implemented” by “subclasses” Interfaces cannot be instantiated, but can be “implemented” by “subclasses” Interfaces cannot have variables, only constants Interfaces cannot have variables, only constants Inner class Inner class A class that is declared nested inside another class declaration A class that is declared nested inside another class declaration Its scope is only within the class in which it is declared Its scope is only within the class in which it is declared Can refer to any members of its outer class. Can refer to any members of its outer class.


Download ppt "Class Inheritance Part II: Overriding and Polymorphism Corresponds with Chapter 10."

Similar presentations


Ads by Google