100. Java 继承 - 子类的功能与扩展
继承概述
在 Java
中,继承(Inheritance
)允许子类(subclass
)从父类(superclass
)继承字段和方法,从而实现代码复用,并建立类之间的层次关系。
子类可以:
- 直接使用继承的字段和方法。
- 通过 覆盖(
override
) 方法来修改超类的行为。 -
隐藏(
hide
) 超类的静态方法(不推荐)。 - 声明新的字段和方法。
- 通过
super
关键字调用超类的构造函数或方法。
1. 继承的字段与方法
1.1 继承字段的使用
class Parent {
public int age = 50;
}
class Child extends Parent {
public void showAge() {
System.out.println("父类的年龄: " + age);
}
}
public class InheritanceDemo {
public static void main(String[] args) {
Child child = new Child();
child.showAge(); // 输出: 父类的年龄: 50
}
}
解释: 由于 age
是 public
的,子类 Child
直接继承了它并可以直接访问。
1.2 字段隐藏(不推荐)
如果子类声明了与超类同名的字段,则超类的字段在子类中被隐藏(而非覆盖)。
class Parent {
public int value = 10;
}
class Child extends Parent {
public int value = 20; // 隐藏父类的 value
public void display() {
System.out.println("子类的 value: " + value);
System.out.println("父类的 value: " + super.value);
}
}
public class FieldHidingDemo {
public static void main(String[] args) {
Child child = new Child();
child.display();
// 输出:
// 子类的 value: 20
// 父类的 value: 10
}
}
建议: 避免字段隐藏,因为它可能会导致代码的可读性和可维护性下降。
2. 方法的继承、覆盖与隐藏
2.1 继承方法
子类可以直接使用超类的方法,例如:
class Parent {
public void greet() {
System.out.println("Hello from Parent!");
}
}
class Child extends Parent {}
public class MethodInheritanceDemo {
public static void main(String[] args) {
Child child = new Child();
child.greet(); // 输出: Hello from Parent!
}
}
2.2 方法覆盖(Override)
子类可以重写(Override)超类的方法,以修改其行为。
class Parent {
public void greet() {
System.out.println("Hello from Parent!");
}
}
class Child extends Parent {
@Override
public void greet() {
System.out.println("Hello from Child!");
}
}
public class MethodOverrideDemo {
public static void main(String[] args) {
Child child = new Child();
child.greet(); // 输出: Hello from Child!
}
}
关键点:
- 使用
@Override
注解,让编译器检查是否正确覆盖了父类方法。 - 重写的方法必须具有相同的返回类型和参数列表。
2.3 静态方法的隐藏(不推荐)
如果子类声明了与超类相同的静态方法,则该方法会被隐藏(而不是覆盖)。
class Parent {
public static void staticMethod() {
System.out.println("Static method in Parent");
}
}
class Child extends Parent {
public static void staticMethod() {
System.out.println("Static method in Child");
}
}
public class StaticMethodHidingDemo {
public static void main(String[] args) {
Parent p = new Child();
p.staticMethod(); // 输出: Static method in Parent
}
}
注意: 静态方法是基于类调用的,而不是基于对象,因此 p.staticMethod()
仍然调用 Parent
类的方法,而不是 Child
。
3. 使用 super
访问超类成员
3.1 调用超类的方法
class Parent {
public void greet() {
System.out.println("Hello from Parent!");
}
}
class Child extends Parent {
@Override
public void greet() {
super.greet(); // 调用父类的方法
System.out.println("Hello from Child!");
}
}
public class SuperMethodDemo {
public static void main(String[] args) {
Child child = new Child();
child.greet();
// 输出:
// Hello from Parent!
// Hello from Child!
}
}
3.2 调用超类的构造函数
class Parent {
public Parent(String message) {
System.out.println("Parent Constructor: " + message);
}
}
class Child extends Parent {
public Child(String message) {
super(message); // 调用父类的构造函数
System.out.println("Child Constructor");
}
}
public class SuperConstructorDemo {
public static void main(String[] args) {
Child child = new Child("Hello");
// 输出:
// Parent Constructor: Hello
// Child Constructor
}
}
总结:
-
super
关键字用于调用超类的构造函数,必须是子类构造函数的第一行。 - 若超类没有无参构造函数,子类必须显式调用超类的构造函数。
结论
继承是 Java 面向对象编程的核心概念,它允许代码复用并增强可维护性。理解方法覆盖、字段隐藏 和 super 关键字的使用,有助于编写更加高效、清晰的 Java 代码。
🔥 最佳实践 🔥
- 优先使用方法覆盖,而不是字段隐藏。
- 使用
@Override
确保正确覆盖方法。 - 避免隐藏静态方法,以减少代码混淆。
💡 思考问题:
-
Java
为什么不允许多继承? -
final
关键字如何影响继承?