Inheritance in Java
Inheritance is one of the fundamental concepts in object-oriented programming. In Java, we can define a child class that reuses (inherits), extends, or modifies the behavior of a parent class (or base class.). This child class also known as subclass.
Inheritance in Polygon as Base Class
Inheritance Modifiers
Java introduces the following class-level statements and modifiers to support inheritance:
extends
statement is used to declare a new class based on an existing class.final
statement is to prevent a class as a base class, means no class can extend it.abstract
statement specifies that the class is intended for use as a base class only. Instances of abstract classes cannot be created directly (initialize); they must be used as a base class (or extended).
The following section describes some of the rules for inheritance, and the modifiers you can use to change the way classes inherit or are inherited:
- By default, all classes are inheritable unless marked with the final keyword.
- Java support single inheritance only. That is, a class can only inherit from a single class. However, inheritance is transitive, which allows you to define an inheritance hierarchy for a set of types. In other words, type Duck can inherit from type WaterBird, which inherits from type Bird, which inherits from the base class type Animal. Because inheritance is transitive, the protected and public members of type Animal are available to type Duck.
Overriding Methods in Subclasses
By default, a subclass inherits methods from its base class. If an inherited method has to behave differently in the subclass it can be overridden. That is, you can define a new implementation of the method in the subclass. The following annotation and modifiers are used to control how methods are overridden:
@Override
will overrides an overridable method defined in the base class.@Override
is optional, to validate that a base class method with the same signature is really exists.final
statement prevents a method from being overridden in an inheriting class.abstract
statement requires that a derived class override the method. When theabstract
keyword is used, the method is declared without an implementation (without braces, and followed by a semicolon) . If a class includesabstract
methods, then the class itself must be declaredabstract
.
Following is an example demonstrating Java inheritance. In this example, you can observe two classes namely BaseClass and SubClass.
import java.math.BigDecimal; public class BaseClass { public BigDecimal calculatePayment(int number, BigDecimal price) { return new BigDecimal(number).multiply(price); } public String settlePayment(BigDecimal payment) { return payment.setScale(2, BigDecimal.ROUND_HALF_UP).toString() + " is settled"; } }
import java.math.BigDecimal; public class SubClass extends BaseClass { @Override public BigDecimal calculatePayment(int number, BigDecimal price) { // Call the method in the base class and modify the return value. return super.calculatePayment(number, price).multiply(new BigDecimal("2")); } }
Using extends keyword, the SubClass inherits the methods "calculatePayment" and "settlePayment" of BaseClass. Method calculatePayment(int number, BigDecimal price) is overrided in SubClass.
And below is an example demonstrating Java final class. When a subclass extends from Final, it will throw compilation error: cannot inherit from final FinalClass
public final class FinalClass { public String finalSay() { return "I'm final"; } }
The super Keyword
You can use the super keyword to call methods in a base class when you override methods in a subclass. As in above example, SubClass overrides method calculatePayment(...) inherited from BaseClass. The overridden method can call method calculatePayment(...) in BaseClass and modify the return value.
The following list describes restrictions on using super:
- super refers to the immediate base class and its inherited members, super cannot be used to access base class members that are marked as private.
- The method that super qualifies does not have to be defined in the immediate base class; it may instead be defined in an indirectly inherited base class. During compilation, compiler will check the reference qualified by super, so base class (or classes) must contain a method matching the name and the parameters in the call.
- super is a keyword, not a real object. super cannot be assigned to a variable, passed to methods, or used in a comparison.
- You cannot use super to call an abstract method in base class (this is no brainier).
- super cannot be used to qualify itself. Therefore, the following code is not valid:
super.super.doSomething();
When Do We Use Inheritance?
Inheritance is a useful programming concept, but we must understand on how to use it effectively. In Java, sometimes we struggle when to use interface, or when to use base class (inheritance). In some cases, interfaces can do the job better. We must understand the reason behind each approach. Inheritance is a good choice when:
- Your inheritance hierarchy represents an "is-a" relationship and not a "has-a" relationship (example: Bird is an Animal)
- You can reuse code from the base classes.
- You need to apply the same class and methods to different data types.
- The class hierarchy is reasonably shallow, and other developers are not likely to add many more levels.
- You want to make global changes to derived classes by changing a base class.