Java Inheritance Written by John Bell for CS 342, Spring 2018 Based on chapter 6 of Learning Java by Niemeyer & Leuck, and other sources. Review Which of the following is true? A. Java classes may either extend another class or implement an interface, but not both. B. Java classes may extend another class and/or implement an interface, but no more than one of either. C. Java classes may extend at most one other class, and may implement as many interfaces as they wish. D. Java classes may extend as many classes as they wish, but may not implement more than one interface. E. Java classes may extent as many classes as they wish, and may implement as many interfaces as they wish. 1
Java Inheritance Basics Java implements inheritance with extends keyword. Java classes may only extend from one parent. Java classes with no specified parent inherit from Object. Abstract classes dictate required methods, but do not provide ( all of ) them. They must be extended before they can be instantiated. Interfaces are like (pure) abstract classes. Java classes may implement as many Interfaces as desired. class Parent { int vara; Inheritance and Scope ( Shadowed Variables ) // super.vara class Child extends Parent { double vara; // this.vara method( ) { float vara; // unqualified vara // Note: super, this not always needed. 2
Method Overriding @Override marker The @Override marker notifies the compiler that the intention is to override an inherited method, not to create a new overloaded method. Compiler will generate error messages if the method does not exist in an ancestor class. class Cat extends Mammal {... @Override void sleep() {... 3
Overriding Methods versus Shadowing Variables If a superclass variable is used to reference a subclass object, access to variables will get the ones defined in the superclass, but access to methods will get the ones in the subclass. Cat simon = new Cat(); Animal creature = simon;... creature.sleep(); // accesses Cat sleep(); creature.weight = 1; // accesses Animal.weight ( Variables uses static binding at compile time; Methods use dynamic binding at run time. ) More Binding Issues Overloaded methods are bound statically at compile time. Overridden methods are bound dynamically at run time. ( Keyword virtual in C++ ) Static methods are bound statically at compile time. Static methods in subclasses can shadow static methods in superclasses ( if not declared final ), only when accessed through a class variable. Superclass method is always available through superclass name. A static method may not be overridden with a non-static method. 4
Exceptions and Overridden Methods A subclass may refine the throws clause in an overriding method to a subtype of the Throwable type specified by its ancestor. ( It may not throw things its ancestor didn t, but it may specify a subset of its ancestor s throws list. ) Callers of the method accessing via a subclass variable only have to handle the subset of Throwables specified in the subclass throws clause, not the full set specified by the ancestor. Return Types and Overridden Methods A subclass may refine the return type in an overriding method to a subtype of the return type specified by its ancestor. ( It may return a refined version of what its ancestor returned. ) class Animal { Animal create() {... class Mammal extends Animal { Mammal create() {... // A Mammal IS A Animal 5
this and super revisited class GrandParent { int vara; // super.super.vara?? Not allowed with methods int varb; // super.varb class Parent { float vara; // super.vara class Child extends Parent { double vara; // this.vara double varb; // unqualified varb method( ) { float vara; // unqualified vara Casting Upcasting to an ancestor type is safe. Downcasting to a descendant type is dangerous. Check using instanceof before downcasting. Errors will result from improper casting. Casting can affect selection of statically bound members, but not dynamically bound ones. ( See next Slide ) 6
Casting and selection of methods and variables Review of this and super in constructors Every descendant constructor must call a superclass constructor before doing its own work. super( arguments ) may be used to call a specific superclass constructor. If no super( arguments ) or super( ) or this(... ) is written by the programmer, the system will insert super( ) automatically. ( May cause errors. ) this( arguments ) may be used instead of super( ) to call another constructor of this class, which must in turn call super(... ) or this(... ) 7
Interfaces Interfaces work like (pure) abstract classes. An interface specifies a list of capabilities of a class, i.e. a guarantee of certain methods available. Classes may implement multiple interfaces. Interfaces may extend ( multiple ) interfaces. Methods with same names but different signatures are simply overloaded. Methods with same names that differ only by return types or exceptions thrown generate errors. static final variables defined in an Interface are available in any class that implements the Interface, or publicly through the Interface name. Lecture Switches to Textbook at This Point Learning Java by Niemeyer & Leuck, 4 th Edition, O Reilly 8