Building a parent–child relationship with extends
Inheritance is one of Java’s core object-oriented features. By using the extends keyword, one class can be connected to another as its child class, or subclass, and the existing class becomes its parent class, or superclass.
A subclass can inherit the parent class’s non-private member variables and member methods. This means that an object created from the subclass is assembled from both the subclass and the parent class: the subclass supplies its own members while also containing the inherited part of the parent.
Access control in an inheritance hierarchy
Access modifiers determine where a class member—such as a field, method, constructor, or code block—can be accessed. Their visibility is summarized below:
<table> <thead> <tr> <th>Modifier</th> <th>Within the declaring class</th> <th>Other classes in the same package</th> <th>Subclasses in any package</th> <th>Any class in any package</th> </tr> </thead> <tbody> <tr> <td>private</td>
<td>✓</td>
<td></td>
<td></td>
<td></td>
</tr>
<tr>
<td>package-private</td>
<td>✓</td>
<td>✓</td>
<td></td>
<td></td>
</tr>
<tr>
<td>protected</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td></td>
</tr>
<tr>
<td>public</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
<td>✓</td>
</tr>
</tbody>
</table>
The scope of access increases in this order:
private < package-private < protected < public
Java supports single inheritance
A Java class can extend only one direct parent class, so Java does not support multiple inheritance for classes. It does, however, support multilevel inheritance, in which one class extends another class that already extends a different class.
The role of Object
Object is the root class of the Java class hierarchy. Every Java class is ultimately a subclass of Object, whether that relationship is written explicitly or not.
Overriding a parent method
When a parent method does not fully meet a subclass’s needs, the subclass can provide a new implementation with the same method name and parameter list. This is called method overriding. After overriding takes place, Java follows the nearest applicable method when deciding which implementation to use.
The @Override annotation should normally be placed above an overriding method. It asks the compiler to verify that the method really follows the rules for overriding and also makes the code easier to understand.
Several restrictions apply:
- The overriding method’s access level must be at least as broad as that of the parent method. In practice, the order is
public > protected > package-private. - The return type must be the same as the original method’s return type, or a narrower compatible type.
- Private methods and static methods cannot be overridden. Attempting to treat them as overridden methods results in an error.
A common practical use of overriding is for a subclass to override Object’s toString() method so that printing the object returns meaningful information about its contents rather than the default representation.
How a subclass resolves members
When code inside a subclass accesses another member, Java searches according to proximity:
- The local scope of the current subclass method is checked first.
- The members of the subclass are checked next.
- The parent class’s members are then considered.
- If the search still finds nothing in the parent class, the compiler reports an error.
If the parent and child classes contain members with the same name, the subclass member takes precedence. When the subclass must explicitly access the parent implementation or field, it can use the super keyword:
super.父类成员变量/父类成员方法
Constructor execution in a subclass
Every constructor in a subclass calls a constructor in the parent class before executing the subclass’s own initialization code. Under Java’s default behavior, the first line of each subclass constructor is effectively:
super();
Whether written explicitly or not, this call invokes the parent’s no-argument constructor.
If the parent class does not provide a no-argument constructor, the subclass constructor must explicitly call an available parent constructor in its first line with super(...), supplying the required arguments. This ensures that the parent portion of the object is initialized before the subclass portion is constructed.