- Start with Inheritence here
- A subclass inherits all the members (fields, methods, and nested classes) from its superclass. Constructors are not members, so they are not inherited by subclasses, but the constructor of the superclass can be invoked from the subclass.
public class Bicycle {
// the Bicycle class has three fields
public int cadence;
public int gear;
public int speed;
// the Bicycle class has one constructor
public Bicycle(int startCadence, int startSpeed, int startGear) {
gear = startGear;
cadence = startCadence;
speed = startSpeed;
}
// the Bicycle class has four methods
public void setCadence(int newValue) {
cadence = newValue;
}
public void setGear(int newValue) {
gear = newValue;
}
public void applyBrake(int decrement) {
speed -= decrement;
}
public void speedUp(int increment) {
speed += increment;
}
}
public class MountainBike extends Bicycle {
// the MountainBike subclass adds one field
public int seatHeight;
// the MountainBike subclass has one constructor
public MountainBike(int startHeight,
int startCadence,
int startSpeed,
int startGear) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
// the MountainBike subclass adds one method
public void setHeight(int newValue) {
seatHeight = newValue;
}
}
- A subclass inherits all of the public and protected members of its parent, no matter what package the subclass is in. If the subclass is in the same package as its parent, it also inherits the package-private members of the parent.
- Explicit casting:
MountainBike myBike = (MountainBike)obj;
if (obj instanceof MountainBike) {
MountainBike myBike = (MountainBike)obj;
}
- The distinction between hiding a static method and overriding an instance method has important implications:
* The version of the overridden instance method that gets invoked is the one in the subclass.
* The version of the hidden static method that gets invoked depends on whether it is invoked from the superclass or the subclass.
public class Animal {
public static void testClassMethod() {
System.out.println("The static method in Animal");
}
public void testInstanceMethod() {
System.out.println("The instance method in Animal");
}
}
public class Cat extends Animal {
public static void testClassMethod() {
System.out.println("The static method in Cat");
}
public void testInstanceMethod() {
System.out.println("The instance method in Cat");
}
public static void main(String[] args) {
Cat myCat = new Cat();
Animal myAnimal = myCat;
Animal.testClassMethod();
myAnimal.testInstanceMethod();
}
}
Output:
The static method in Animal
The instance method in Cat
Defining a Method with the Same Signature as a Superclass's Method
|
Superclass Instance Method |
Superclass Static Method |
Subclass Instance Method |
Overrides |
Generates a compile-time error |
Subclass Static Method |
Generates a compile-time error |
Hides |
- Instance methods are preferred over interface default methods.
public class Horse {
public String identifyMyself() {
return "I am a horse.";
}
}
public interface Flyer {
default public String identifyMyself() {
return "I am able to fly.";
}
}
public interface Mythical {
default public String identifyMyself() {
return "I am a mythical creature.";
}
}
public class Pegasus extends Horse implements Flyer, Mythical {
public static void main(String... args) {
Pegasus myApp = new Pegasus();
System.out.println(myApp.identifyMyself());
}
}
The method Pegasus.identifyMyself
returns the string I am a horse.
- Methods that are already overridden by other candidates are ignored. This circumstance can arise when supertypes share a common ancestor.
public interface Animal {
default public String identifyMyself() {
return "I am an animal.";
}
}
public interface EggLayer extends Animal {
default public String identifyMyself() {
return "I am able to lay eggs.";
}
}
public interface FireBreather extends Animal { }
public class Dragon implements EggLayer, FireBreather {
public static void main (String... args) {
Dragon myApp = new Dragon();
System.out.println(myApp.identifyMyself());
}
}
The method Dragon.identifyMyself
returns the string I am able to lay eggs.
public interface OperateCar {
// ...
default public int startEngine(EncryptedKey key) {
// Implementation
}
}
public interface FlyCar {
// ...
default public int startEngine(EncryptedKey key) {
// Implementation
}
}
A class that implements both OperateCar
and FlyCar
must override the method startEngine
. You could invoke any of the of the default implementations with the super
keyword.
public class FlyingCar implements OperateCar, FlyCar {
// ...
public int startEngine(EncryptedKey key) {
FlyCar.super.startEngine(key);
OperateCar.super.startEngine(key);
}
}
- Note: Static methods in interfaces are never inherited.
- The access specifier for an overriding method can allow more, but not less, access than the overridden method. For example, a protected instance method in the superclass can be made public, but not private, in the subclass. You will get a compile-time error if you attempt to change an instance method in the superclass to a static method in the subclass, and vice versa.
- Note: In a subclass, you can overload the methods inherited from the superclass. Such overloaded methods neither hide nor override the superclass instance methods—they are new methods, unique to the subclass.
public MountainBike(int startHeight,
int startCadence,
int startSpeed,
int startGear) {
super(startCadence, startSpeed, startGear);
seatHeight = startHeight;
}
Invocation of a superclass constructor must be the first line in the subclass constructor.
- Note: If a constructor does not explicitly invoke a superclass constructor, the Java compiler automatically inserts a call to the no-argument constructor of the superclass. If the super class does not have a no-argument constructor, you will get a compile-time error. Object does have such a constructor, so if Object is the only superclass, there is no problem.
protected Object clone() throws CloneNotSupportedException
or:
public Object clone() throws CloneNotSupportedException
public class Book {
...
public boolean equals(Object obj) {
if (obj instanceof Book)
return ISBN.equals((Book)obj.getISBN());
else
return false;
}
}
Consider this code that tests two instances of the Book class for equality:
// Swing Tutorial, 2nd edition
Book firstBook = new Book("0201914670");
Book secondBook = new Book("0201914670");
if (firstBook.equals(secondBook)) {
System.out.println("objects are equal");
} else {
System.out.println("objects are not equal");
}
- Note: If you override equals(), you must override hashCode() as well.
-
You cannot override getClass.
-
The getClass()
method returns a Class
object, which has methods you can use to get information about the class, such as its name (getSimpleName()
), its superclass (getSuperclass()
), and the interfaces it implements (getInterfaces()
). For example, the following method gets and displays the class name of an object:
void printClassName(Object obj) {
System.out.println("The object's" + " class is " +
obj.getClass().getSimpleName());
}
The Class
class, in the java.lang
package, has a large number of methods (more than 50). For example, you can test to see if the class is an annotation (isAnnotation()
), an interface (isInterface()
), or an enumeration (isEnum()
). You can see what the object's fields are (getFields()
) or what its methods are (getMethods()
), and so on.
System.out.println(firstBook.toString());
which would, for a properly overridden toString()
method, print something useful, like this:
ISBN: 0201914670; The Swing Tutorial; A Guide to Constructing GUIs, 2nd Edition
class ChessAlgorithm {
enum ChessPlayer { WHITE, BLACK }
...
final ChessPlayer getFirstPlayer() {
return ChessPlayer.WHITE;
}
...
}
-
Methods called from constructors should generally be declared final. If a constructor calls a non-final method, a subclass may redefine that method with surprising or undesirable results.
-
Note that you can also declare an entire class final
. A class that is declared final cannot be subclassed. This is particularly useful, for example, when creating an immutable class like the String
class.
- An abstract class is a class that is declared
abstract
—it may or may not include abstract methods. Abstract classes cannot be instantiated, but they can be subclassed.
An abstract method is a method that is declared without an implementation (without braces, and followed by a semicolon), like this:
abstract void moveTo(double deltaX, double deltaY);
If a class includes abstract methods, then the class itself must be declared abstract, as in:
public abstract class GraphicObject {
// declare fields
// declare nonabstract methods
abstract void draw();
}
When an abstract class is subclassed, the subclass usually provides implementations for all of the abstract methods in its parent class. However, if it does not, then the subclass must also be declared abstract
.
Note: Methods in an interface (see the Interfaces section) that are not declared as default or static are implicitly abstract, so the abstract
modifier is not used with interface methods. (It can be used, but it is unnecessary.)
abstract class GraphicObject {
int x, y;
...
void moveTo(int newX, int newY) {
...
}
abstract void draw();
abstract void resize();
}
class Circle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
class Rectangle extends GraphicObject {
void draw() {
...
}
void resize() {
...
}
}
- An abstract class does not have to fully implement an interface but concrete subclasses must implement anything ignored by the abstract class. Example below:
abstract class X implements Y {
// implements all but one method of Y
}
class XX extends X {
// implements the remaining method in Y
}