Chapter 8 Class Inheritance and Interfaces Superclasses and Subclasses Keywords: super Overriding methods The Object Class Modifiers: protected, final and abstract Abstract classes Polymorphism and Object Casting Interfaces Inner Classes Superclasses and Subclasses Superclass Circle Circle Methods Circle Data Inheritance Subclass UML Diagram Cylinder Circle Methods Cylinder Methods Circle Data Cylinder Data Superclass Subclass Circle Cylinder -radius -length +getRadius +setRadius +findArea +getLength +setLength +findVolume Creating a Subclass Creating a subclass extends properties and methods from the superclass. You can also: Add new properties Add new methods Override the methods of the superclass Cylinder Class Example 8.1 Testing Inheritance Create a Cylinder object and explore the relationship between the Cylinder and Circle classes. Objective: TestCylinder Run Using the Keyword super The keyword super refers to the superclass of the class in which super appears. This keyword can be used in two ways: To call a superclass constructor To call a superclass method CAUTION You must use the keyword super to call the superclass constructor. Invoking a superclass constructor’s name in a subclass causes a syntax error. Java requires that the statement that uses the keyword super appear first in the constructor. NOTE A constructor is used to construct an instance of a class. Unlike properties and methods, a superclass's constructors are not inherited in the subclass. They can only be invoked from the subclasses' constructors, using the keyword super. If the keyword super is not Example on Calling Superclass’s Constructors public class C1 extends C2 { public static void main(String[] args) { new C1(); } public C1() { System.out.println("C1's default constructor is invoked"); } } class C2 extends C3 { public C2() { System.out.println("C2's default constructor is invoked"); } } class C3 { public C3() { System.out.println("C3's default constructor is invoked"); } NOTE If a superclass defines constructors other than a default constructor, the subclass cannot use the default constructor of the superclass, because in this case the superclass does not have a default constructor. Example on the Impact of a Superclass with no Default Constructor public class A extends B { } class B { public B(String name) { System.out.println("B's constructor is invoked"); } } Example 8.2 Overriding Methods in the Superclass The Cylinder class overrides the findArea() method defined in the Circle class. Cylinder TestOverrideMethod Run NOTE An instance method can be overridden only if it is accessible. Thus a private method cannot be overridden, because it is not accessible outside its own class. If a method defined in a subclass is private in its superclass, the two methods are completely unrelated. NOTE Like an instance method, a static method can be inherited. However, a static method cannot be overridden. If a method defined in the superclass is redefined in a subclass, the method defined in the superclass is hidden. The Object Class The Object class is the root of all Java classes. The equals() method compares the contents of two objects. The toString() method returns a string representation of the object. The clone() method copy objects The Object Class, cont. The equals() method compares the contents of two objects. The default implementation of the equals method in the Object class is as follows: public boolean equals(Object obj) { return (this == obj); } NOTE The == comparison operator is used for comparing two primitive data type values or for determining whether two objects have the same references. The equals method is intended to test whether two objects have the same contents, provided that the method is modified in the defining class of the objects. The Object Class, cont. The toString() method returns a string representation of the object. The default implementation returns a string consisting of a class name of which the object is an instance, the at sign (@), and a number representing this object. The clone() method copy objects The Object Class, cont. To create a new object with separate memory space, you need to use the clone() method, as follows: newObject = someObject.clone(); NOTE: Not all objects can be cloned. For an object to be cloneable, its class must implement the java.lang.Cloneable interface. Interfaces are introduced in the section "Interfaces," in this The protected Modifier protected modifier can be applied on data and methods in a class. A protected data or a protected method in a public class can be accessed by any class in the same package or its subclasses, even if the subclasses are in a different package. The The protected Modifier, cont. pacakge p1 class C1 protected int x class C3 C1 c1; c1.x can be read or modified pacakge p2 class C2 extends C1 x can be read or modified in C2 class C4 C1 c1; c1.x cannot be read nor modified NOTE A subclass may override a protected method in its superclass and change its visibility to public. However, a subclass cannot weaken the accessibility of a method defined in the superclass. For example, if a method is defined as public in the superclass, it NOTE The modifiers are used on classes and class members (data and methods), except that the final modifier can also be used on local variables in a method. A final local variable is a constant inside a method. The final Modifier The final class cannot be extended: final class Math { ... } The final variable is a constant: final static double PI = 3.14159; The final method cannot be modified by its subclasses. The abstract Modifier The abstract class – Cannot be instantiated – Should be extended and implemented in subclasses The abstract method – Method signature without implementation Abstract Classes UML Notation: The abstract class name and the abstract method names are italicized. Object GeometricObject -color: String -filled: boolean +getColor(): String +setColor(String color): void +isFilled(): boolean +setFilled(boolean filled): void +findArea(): double +findPerimeter(): double Circle -radius: double -length: double +getRadius(): double +setRadius(radius: double): void +getLength(): double +setLength(length: double): void +findVolume(): double Rectangle -width: double -length: double +getWidth(): double +setWidth(width: double): void +getLength(): double +setLength(length: double): void GeometricObject Circle Cylinder Cylinder Rectangle NOTE An abstract method cannot be contained in a nonabstract class. If a subclass of an abstract superclass does not implement all the abstract methods, the subclass must be declared abstract. In other words, in a nonabstract subclass extended from an abstract NOTE An abstract class cannot be instantiated using the new operator, but you can still define its constructors, which are invoked in the constructors of its subclasses. For instance, the constructors of GeometricObject are invoked in the Circle class and the NOTE A class that contains abstract methods must be abstract. However, it is possible to declare an abstract class that contains no abstract methods. In this case, you cannot create instances of the class using the new operator. This class is used as a base class for NOTE A subclass can be abstract even if its superclass is concrete. For example, the Object class is concrete, but its subclasses, such as GeometricObject, may be abstract. NOTE A subclass can override a method from its superclass to declare it abstract. This is rare, but useful when the implementation of the method in the superclass becomes invalid in the subclass. In this case, the subclass must be declared abstract. NOTE You cannot create an instance from an abstract class using the new operator, but an abstract class can be used as a data type. Therefore, the following statement, which creates an array whose elements are of GeometricObject type, is NOTE Cylinder inherits the findPerimeter method from Circle. If you invoke this method on a Cylinder object, the perimeter of a circle is returned. This method is not useful for Cylinder objects. It would be nice to remove or disable it from Cylinder, but there is no good way to get rid of this method in a subclass once it is defined as Polymorphism, Dynamic Binding and Generic Programming Consider the following code: Test Polymorphism Method m (Line 9) takes a parameter of the Object type. You can invoke m with any objects (e.g. new A(), new B(), new C(), and new Object())in Lines (3-6). An object of a subclass can be used by any code designed to work with an object of its superclass. This feature is known as Dynamic Binding When the method m is executed, the argument x’s toString method is invoked. x may be an instance of A, B, C, or Object. Classes A, B, C, and Object have their own implementation of the toString method. Which implementation is used will be determined dynamically by the Java Virtual Machine at Dynamic Binding, cont. Dynamic binding works as follows: Suppose an object o is an instance of classes C1, C2, ..., Cn-1, and Cn, where C1 is a subclass of C2, C2 is a subclass of C3, ..., and Cn-1 is a subclass of Cn. That is, Cn is the most general class, and C1 is the most specific class. In Java, Cn is the Object class. If o invokes a method p, the JVM searches the implementation for the method p in C1, C2, ..., Cn-1 and Cn, in this order, until it is found. Once an implementation is found, the search stops and the first- Generic Programming Polymorphism allows methods to be used generically for a wide range of object arguments. This is known as generic programming. If a method’s parameter type is a superclass (e.g., GeometricObject), you may pass an object to this method of any of the parameter’s subclasses (e.g., Circle or Rectangle). When an object (e.g., a Circle object or a Rectangle object) is used in Example 8.3 Testing Polymorphism Objective: This example creates two geometric objects: a circle, and a rectangle, invokes the equalArea method to check if the two objects have equal area, and invokes the displayGeometricObject method to display the objects. TestPolymorphism Run NOTE Matching a method signature and binding a method implementation are two issues. The compiler finds a matching method according to parameter type, number of parameters, and order of the parameters at compilation time. A method may be implemented in several Casting Objects It is always possible to convert a subclass to a superclass. For this reason, explicit casting can be omitted. For example, Circle myCircle = myCylinder is equivalent to Circle myCircle = (Circle)myCylinder; Casting from Superclass to Subclass Explicit casting must be used when casting an object from a superclass to a subclass. This type of casting may not always succeed. Cylinder myCylinder = (Cylinder)myCircle; The instanceof Operator Use the instanceof operator to test whether an object is an instance of a class: Circle myCircle = new Circle(); if (myCircle instanceof Cylinder) { Cylinder myCylinder = (Cylinder)myCircle; ... } Example 8.4 Casting Objects This example creates two geometric objects: a circle, and a cylinder, invokes the displayGeometricObject method to display the objects. The displayGeometricObject displays the area and perimeter if the object is a circle, and displays area and volume if the object is a cylinder. TestCasting Run Interfaces What Is an Interface? Creating an Interface Implementing What an Interface is Marker Interface? Creating an Interface modifier interface InterfaceName { constants declarations; methods signatures; } Example of Creating an Interface // This interface is defined in // java.lang package public interface Comparable { public int compareTo(Object o); } Generic max Method public class Max { // Return the maximum between two objects public static Comparable max (Comparable o1, Comparable o2) { if (o1.compareTo(o2) > 0) return o1; else return o2; } } Example 8.5 Using Interfaces Objective: Use the max method to find a find the maximum circle between two circles and a maximum cylinder between two cylinders. Example 8.5, cont. Notation: The interface name and the method names are italicized. The dashed lines and hollow triangles are used to point to the interface. GeometricObject Circle - Cylinder java.lang.Comparable ComparableCircle - ComparableCylinder - compareTo TestInterface Run Interfaces vs. Abstract Classes In an interface, the data must be constants; an abstract class can have all types of data. Each method in an interface has only a signature without implementation; an abstract class can have concrete methods. An abstract class must contain at least one abstract method or inherit from another abstract method. Interfaces vs. Abstract Classes, cont. Since all the methods defined in an interface are abstract methods, Java does not require you to put the abstract modifier in the methods in an interface, but you must put the abstract modifier before an abstract method in an abstract class. Interfaces vs. Abstract Classes, cont. Interface1_2 Interface1_1 Object Interface2_2 Interface1 Class1 Interface2_1 Class2 The Cloneable Interfaces Marker Interface: An empty interface. A marker interface does not contain constants or methods, but it has a special meaning to the Java system. The Java system requires a class to implement the Cloneable interface to become cloneable. public interface Cloneable { } Example 8.6 Cloning Objects Objective: uses the Cloneable interface to mark classes cloneable and uses the clone method to copy objects. TestCloneable Run Example 8.6 Cloning Objects, cont. Memory c1: CloneableCircle radius = 5 creator = {"Yong", ‘D’, "Liang") c2: CloneableCircle radius = 5 creator = {"Yong", ‘D’, "Liang") 5 reference creator: Name firstname = "Yong" mi = ‘D’ firstname = "Liang" 5 reference Inner Classes Inner class: A class is a member of another class. Advantages: In some applications, you can use an inner class to make programs simple. An inner class can reference the data and methods defined in the outer class in which it nests, so you do not need to pass the reference of the outer class to the constructor of the inner class. ShowInnerClass Inner Classes (cont.) Inner classes can make programs simple and concise. As you see, the new class is shorter and leaner. Many Java development tools use inner classes to generate adapters for handling events. Event-driven programming is introduced in Chapter 8, "Getting Started with Graphics Programming.” An inner class is only for supporting the work of its containing outer class, and it cannot be used by other classes. Initialization Block Initialization blocks can be used to initialize objects along with the constructors. An initialization block is a block of statements enclosed inside a pair of braces. An initialization block appears within the class declaration, but not inside methods or constructors. It is executed as if it were placed at the beginning of every Initialization Block public class Book { { numOfObjects++; } } Static Initialization Block A static initialization block is much like a nonstatic initialization block except that it is declared static, can only refer to static members of the class, and is invoked when the class is loaded. The Java runtime system loads a class when it is needed. A superclass is loaded before its subclasses. Static Initialization Block class A extends B { static { System.out.println("A's static initialization block is invoked"); } } class B { static { System.out.println("B's static initialization block is invoked"); } }