gpt4 book ai didi

java - 当基类和派生类都具有同名变量时会发生什么

转载 作者:行者123 更新时间:2023-12-02 04:21:35 24 4
gpt4 key购买 nike

考虑这些类中的 int a 变量:

class Foo {
public int a = 3;
public void addFive() { a += 5; System.out.print("f "); }
}
class Bar extends Foo {
public int a = 8;
public void addFive() { this.a += 5; System.out.print("b " ); }
}
public class test {
public static void main(String [] args){
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
}
}

据我所知,方法addFive()已在子类中被重写,并且在类测试中,当引用子类的基类引用用于调用重写的方法时,子类调用了 addFive 的版本。

但是公共(public)实例变量a呢?当基类和派生类具有相同的变量时会发生什么?

上述程序的输出为

b 3 

这是怎么发生的?

最佳答案

实际上有两个不同的公共(public)实例变量,称为a

  • Foo 对象有一个 Foo.a 变量。
  • Bar 对象同时具有 Foo.aBar.a 变量。

当您运行此命令时:

    Foo f = new Bar();
f.addFive();
System.out.println(f.a);

addFive 方法正在更新 Bar.a 变量,然后读取 Foo.a 变量。要读取 Bar.a 变量,您需要执行以下操作:

    System.out.println(((Bar) f).a);

这里发生的事情的技术术语是“隐藏”。请参阅 JLS section 8.3 ,和section 8.3.3.2举个例子。

请注意,隐藏也适用于具有相同签名的静态方法。

但是,具有相同签名的实例方法是“重写”而不是“隐藏”,并且您无法从外部访问被重写的方法的版本。 (在重写方法的类中,可以使用 super 调用重写的方法。但是,这是唯一允许这样做的情况。通常禁止访问重写的方法的原因是它会破坏数据抽象。)

<小时/>

避免(意外)隐藏造成困惑的推荐方法是将实例变量声明为私有(private),并通过 getter 和 setter 方法访问它们。使用 getter 和 setter 还有很多其他的充分理由。

<小时/>

还应该注意的是:1)公开公共(public)变量(如a)通常是一个坏主意,因为它会导致弱抽象、不必要的耦合和其他问题。 2) 故意在子类中声明第二个公共(public) a 变量确实是一个糟糕的主意。

关于java - 当基类和派生类都具有同名变量时会发生什么,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56633904/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com