abstract and final
Let's take a remote for shapes. The "Shape" remote has an "Area" button. Point it at a square, and you get the area: the side multiplied by itself. Point it at a circle, and the circle's formula works.
But what is the area of a "shape in general"? There is no such formula, and no such thing either: there are squares, circles, triangles.
So far the parent has always written a method in full, like sound in Animal, which printed .... For a shape such a placeholder does not work: an area method that returns 0 would be telling a lie. Java lets you say it directly: the method exists, but it has no body, and the subclasses will write it.
public class Main {
public static void main(String[] args) {
Shape s = new Square();
System.out.println(s.area()); // 9
}
}
abstract class Shape {
abstract int area();
}
class Square extends Shape {
int side = 3;
@Override int area() { return side * side; }
}Let's walk through the program step by step:
abstract class Shapedeclares an abstract class: there will be noShapeobjects, only objects of its subclasses.abstract int area();is a method without a body: a semicolon stands where the curly braces would be. It promises that every shape will have an area.SquareextendsShapeand overridesarea: the side multiplied by itself.- The variable
sof typeShapeleads to a square, ands.area()runs theSquareversion. It prints9.
Abstract class
An abstract class is a class marked abstract whose objects cannot be created. It serves as the shared parent of its subclasses. What it may contain:
- abstract methods: without a body, marked
abstract; - ordinary methods and fields: the subclasses get them, as from any parent;
- constructors: the subclasses call them through
super(…).
A subclass must write a body for every abstract method. Otherwise the compiler answers Square is not abstract and does not override abstract method area() in Shape. The other way out is to declare the subclass abstract too.
Can you create an object of an abstract class? Interviewers often ask this. No, even when the class has no abstract methods at all: the word abstract itself forbids it.
Here the remote picture is off. A "Shape" remote without a device is useless, while an abstract class is useful on its own. It may hold ready fields and methods, and every subclass gets them.
The final mark
The word final forbids changing what is already there. You have seen it on variables: final does not let you assign a new value. On methods and classes the meaning is similar.
A final method
A subclass cannot override a method marked final:
class Animal {
final void breathe() { System.out.println("in, out"); }
}
class Dog extends Animal {
@Override void breathe() { } // ✗
}error: breathe() in Dog cannot override breathe() in AnimalThis is how a parent protects behavior that must be the same in all its subclasses.
A final class
A class marked final cannot be inherited from at all. If you declare final class Square, then class Big extends Square does not compile: cannot inherit from final Square.
String is declared this way: you cannot inherit from it, and nobody can swap out how strings behave. Interviewers like to ask about this too. And abstract and final never go together: the first needs subclasses, the second forbids them.
The protected access level
Of the four access levels, protected was made for subclasses. A field or method with it is visible to the classes of its own package and to subclasses in any package.
In one file you will not notice a difference from no modifier: all the classes of the program are in one package. It shows up in larger programs, where the parent and the subclass are in different packages.
Common mistake
You tried to create an object of an abstract class:
Shape shape = new Shape(); // ✗error: Shape is abstract; cannot be instantiatedThe program does not compile: Shape is declared abstract, and new is forbidden for it. The compiler finds the error, so the program never starts and none of its lines run. Create an object of a subclass and keep the reference in a variable of the parent's type: Shape s = new Square();.
Key points
- An abstract class is declared with the word
abstract, and no object of it can be created:new Shape()does not compile. - An abstract method has no body, and every ordinary subclass must override it.
- A
finalmethod cannot be overridden, and afinalclass cannot be inherited from;Stringis declared this way. protectedopens a field or method to subclasses, even from another package.