Summary Section 10.1 Introduction • Polymorphism enables us to write programs that process objects that share the same superclass as if they were all objects of the superclass; this can simplify programming. • With polymorphism, we can design and implement systems that are easily extensible. The only parts of a program that must be altered to accommodate new classes are those that require direct knowledge of the new classes that you add to the hierarchy. Section 10.3 Demonstrating Polymorphic Behavior • When the compiler encounters a method call made through a variable, it determines if the method can be called by checking the variable’s class type. If that class contains the proper method declaration (or inherits one), the call is compiled. At execution time, the type of the object to which the variable refers determines the actual method to use. Section 10.4 Abstract Classes and Methods • Abstract classes cannot be used to instantiate objects, because they’re incomplete. • The primary purpose of an abstract class is to provide an appropriate superclass from which other classes can inherit and thus share a common design. • Classes that can be used to instantiate objects are called concrete classes. They provide implementations of every method they declare (some of the implementations can be inherited). • Programmers often write client code that uses only abstract superclasses to reduce client code’s dependencies on specific subclass types. • Abstract classes sometimes constitute several levels of a hierarchy. • An abstract class normally contains one or more abstract methods. • Abstract methods do not provide implementations. • A class that contains any abstract methods must be declared as an abstract class. Each concrete subclass must provide implementations of each of the superclass’s abstract methods. • Constructors and static methods cannot be declared abstract. • Abstract superclass variables can hold references to objects of any concrete class derived from the superclass. Programs typically use such variables to manipulate subclass objects polymorphically. • Polymorphism is particularly effective for implementing layered software systems. Section 10.5 Case Study: Payroll System Using Polymorphism • A hierarchy designer can demand that each concrete subclass provide an appropriate method implementation by including an abstract method in a superclass. • Most method calls are resolved at execution time, based on the type of the object being manipulated. This process is known as dynamic binding or late binding. • A superclass variable can be used to invoke only methods declared in the superclass. • Operator instanceof determines if an object has the is-a relationship with a specific type. • Every object in Java knows its own class and can access it through Object method getClass, which returns an object of type Class (package java.lang). • The is-a relationship applies only between the subclass and its superclasses, not vice versa. Section 10.7 final Methods and Classes • A method that’s declared final in a superclass cannot be overridden in a subclass. • Methods declared private are implicitly final, because you can’t override them in a subclass. • Methods that are declared static are implicitly final. • A final method’s declaration can never change, so all subclasses use the same implementation, and calls to final methods are resolved at compile time—this is known as static binding. • The compiler can optimize programs by removing calls to final methods and inlining their expanded code at each method-call location. • A class that’s declared final cannot be extended. • All methods in a final class are implicitly final. Section 10.9 Creating and Using Interfaces • An interface specifies what operations are allowed but not how they’re performed. • A Java interface describes a set of methods that can be called on an object. • An interface declaration begins with the keyword interface. • All interface members must be public, and interfaces may not specify any implementation details, such as concrete method declarations and instance variables. • All methods declared in an interface are implicitly public abstract methods and all fields are implicitly public, static and final. • To use an interface, a concrete class must specify that it implements the interface and must declare each interface method with the signature specified in the interface declaration. A class that does not implement all the interface’s methods must be declared abstract. • Implementing an interface is like signing a contract with the compiler that states, “I will declare all the methods specified by the interface or I will declare my class abstract.” • An interface is typically used when disparate (i.e., unrelated) classes need to share common methods and constants. This allows objects of unrelated classes to be processed polymorphically—objects of classes that implement the same interface can respond to the same method calls. • You can create an interface that describes the desired functionality, then implement the interface in any classes that require that functionality. • An interface is often used in place of an abstract class when there’s no default implementation to inherit—that is, no instance variables and no default method implementations. • Like public abstract classes, interfaces are typically public types, so they’re normally declared in files by themselves with the same name as the interface and the .java filename extension. • Java does not allow subclasses to inherit from more than one superclass, but it does allow a class to inherit from a superclass and implement more than one interface. • All objects of a class that implement multiple interfaces have the is-a relationship with each implemented interface type. • An interface can declare constants. The constants are implicitly public, static and final. Section 10.10 Java SE 8 Interface Enhancements • In Java SE 8, an interface may declare default methods—that is, public methods with concrete implementations that specify how an operation should be performed. • When a class implements an interface, the class receives the interface’s default concrete implementations if it does not override them. • To declare a default method in an interface, you simply place the keyword default before the method’s return type and provide a complete method body. • When you enhance an existing an interface with default methods—any classes that implemented the original interface will not break—it’ll simply receive the default method implementations. • With default methods, you can declare common method implementations in interfaces (rather than abstract classes), which gives you more flexibility in designing your classes. • As of Java SE 8, interfaces may now include public static methods. • As of Java SE 8, any interface containing only one method is known as a functional interface. There are many such interfaces throughout the Java APIs. • Functional interfaces are used extensively with Java SE 8’s new lambda capabilities. As you’ll see, lambdas provide a shorthand notation for creating anonymous methods. |