Java 继承详解:理解子类继承与方法重写
在面向对象编程中,继承是一个重要的概念。本文将深入探讨子类能够继承和重写父类内容的细节,并讨论继承后的访问特点。
问题1:子类能够继承父类中的哪些内容?
-
构造方法:子类不能继承父类的构造方法。构造方法用于初始化对象,只能由类本身使用。
-
成员变量:子类可以继承父类的所有成员变量(字段),但由于封装性的原因,可能无法直接访问或使用这些字段。
public
字段:子类可以直接访问。protected
字段:子类可以直接访问。- 包访问(默认)字段:如果子类和父类在同一个包中,可以直接访问。
private
字段:子类无法直接访问这些字段,只能通过父类的公共方法(如 getter 和 setter)进行访问。
-
成员方法:子类可以继承父类的所有成员方法,但由于封装性的原因,可能无法直接访问或使用这些方法。
public
方法:子类可以直接访问。protected
方法:子类可以直接访问。- 包访问(默认)方法:如果子类和父类在同一个包中,可以直接访问。
private
方法:子类无法直接访问这些方法。
综上所述,子类能够继承父类的所有属性和方法,但对这些属性和方法的访问受到其访问修饰符的限制。
问题2:子类能够重写父类的哪些方法?
子类只能重写父类的虚方法表中的方法。重写的本质是覆盖虚方法表中的方法。以下几种方法不能被重写:
private
方法:不能被子类重写,因为它们对子类不可见。final
方法:不能被子类重写,因为它们在定义时被标记为最终方法。static
方法:不能被子类重写,因为它们属于类本身,而不是对象实例。
因此,子类只能重写那些没有被 private
、final
和 static
修饰的方法。
问题3:继承后的访问特点
成员变量的访问特点:遵循代码就近原则。具体顺序如下:
- 先在局部位置找(方法内部的局部变量)。
- 在本类成员位置找(本类的字段)。
- 在父类成员位置找,逐级往上查找。
成员方法的访问特点:优先在本类成员位置找,如果没有找到,则在父类成员位置找,逐级往上查找。
结论
通过本文的介绍,我们了解到子类可以继承父类的所有属性和方法,但对这些属性和方法的访问受到访问修饰符的限制。子类只能重写那些没有被 private
、final
和 static
修饰的方法。此外,继承后的成员变量和成员方法的访问遵循特定的查找顺序,这对于理解继承机制和解决实际编程问题非常重要。
示例代码
以下是一个简单的示例代码,展示了子类继承和重写父类的方法和字段:
class Parent {
public int publicField = 1;
protected int protectedField = 2;
int packageField = 3; // 默认访问权限
private int privateField = 4;
public void publicMethod() {
System.out.println("Parent's public method");
}
protected void protectedMethod() {
System.out.println("Parent's protected method");
}
void packageMethod() {
System.out.println("Parent's package method");
}
private void privateMethod() {
System.out.println("Parent's private method");
}
public final void finalMethod() {
System.out.println("Parent's final method");
}
public static void staticMethod() {
System.out.println("Parent's static method");
}
public int getPrivateField() {
return privateField;
}
}
class Child extends Parent {
@Override
public void publicMethod() {
System.out.println("Child's public method");
}
@Override
protected void protectedMethod() {
System.out.println("Child's protected method");
}
@Override
void packageMethod() {
System.out.println("Child's package method");
}
public void displayFields() {
System.out.println("Public field: " + publicField);
System.out.println("Protected field: " + protectedField);
System.out.println("Package field: " + packageField);
System.out.println("Private field via getter: " + getPrivateField());
}
// 这个不是重写
private void privateMethod() {
System.out.println("Child's private method");
}
// 这个不是重写
public static void staticMethod() {
System.out.println("Child's static method");
}
}
public class Main {
public static void main(String[] args) {
Child child = new Child();
child.displayFields();
Parent p = new Child();
p.publicMethod(); // 重写了, 所以调用子类的方法
p.protectedMethod(); // 重写了, 所以调用子类的方法
p.packageMethod(); // 重写了, 所以调用子类的方法
p.staticMethod(); // 没有重写, 调用父类的方法
p.finalMethod(); // 没有重写, 调用父类的方法
}
}
执行结果
Public field: 1
Protected field: 2
Package field: 3
Private field via getter: 4
Child's public method
Child's protected method
Child's package method
Parent's static method
Parent's final method
通过这个示例,我们可以看到子类如何继承和重写父类的字段和方法,以及如何访问这些继承的内容。希望本文能帮助你更好地理解 Java 的继承机制及其在实际编程中的应用。