子类和超类在 Java 中具有相同的属性会发生什么?

  • 本文关键字:属性 超类 Java 子类 java
  • 更新时间 :
  • 英文 :

public class Test {
public static void main(String[] args) {
B b = new B();
b.test();
}
}
class A {
String aString = "a";

void test() {
System.out.println(aString);
}
}
class B extends A {
String aString = "b";
}

为什么不能输入"B"? 我只是认为b.test()会调用超类的方法,所以 b 会用户超类的属性。

为什么不能输入"b"? 我只是认为b.test()会调用superClass的方法,所以b会用户superClass的属性。

Java 类和实例变量可以继承,但它们不是虚拟的。 也就是说,Java 代码中出现的所有变量标识符都在编译时解析 - 它们没有动态解析。

因此,方法A.test()中标识符aString的外观在编译时解析为类AaString属性。 这是该方法的所有调用都将访问的属性,而不考虑调用该方法的对象的实际类。 如果要在类 B 的实例上调用test()时使用该类的属性,请在类AB中提供 getter 方法,并A.test()通过这些方法获取字符串。

b 中的变量隐藏了 a 中的变量。您可以通过删除 b 中的类型来修复它

class B extends A {
public B () {
aString = "b";
}
}
class A {
String aString = "a";

void test() {
System.out.println(aString);
}
}
class B extends A {
String aString = "b";
}

为 B 创建 2 个aString变量。虽然A不知道B扩展它,但B总是可以使用super关键字从其父类A访问"事物"。所以当你在B中时,你可以使用aStringsuper.aString,它们将引用 2 个不同的变量:

class Ideone {
public static void main (String[] args) {
A a=new A();
B b=new B();
a.test();
b.test();
b.suptest();
}

static class A {
String aString="A.aString set from A";
void test() {
System.out.println("A.test(): "+aString);
}
}
static class B extends A {
String aString="B.aString set from B";
{
super.aString="A.aString set from B";
}
void test() {
System.out.println("B.test(): "+aString);
}
void suptest() {
System.out.print("B.suptest() calling super.test(): ");
super.test();
}
}
}

您可以在IdeOne上试用,产生输出

A.test(): A.aString set from A
B.test(): B.aString set from B
B.suptest() calling super.test(): A.test(): A.aString set from B

前两行没有显示任何花哨的东西,A.aStringB.aString都包含它们的初始值.
但是第三行输出显示super.test()调用B实际上在A.test()中"结束",并且B中的初始值设定项块确实改变了继承的aString字段。

(旁注:static class魔术与包含在单个文件中的示例有关,它不会影响继承部分)

你是对的。

由于Class A和方法test()不是抽象的,并且该方法test()未被其subClass B覆盖,因此即使您从B实例调用它,返回也将完全按照Class A中指定的方式。

最新更新