【问题标题】:Member Access Features in Polymorphism in Java [duplicate]Java中多态性中的成员访问功能[重复]
【发布时间】:2020-08-12 02:44:21
【问题描述】:
public class A {
    public int a = 10;
    public void show() {

    }
}

public class B extends A{
    public int a = 20;
    public int b = 10;

    @Override
    public void show() {
        System.out.println(this.a);
    }

    public static void main(String[] args) {
        A a = new B();
        a.show();
        System.out.println(a.a);
    }
}

看上面的代码,我使用父class A引用指向子class B object (A a = new B()),但是当我在main方法中打印a.a(System.out.println(a.a))时,它打印10,因为成员变量a被赋值了10 在父 class A 中。但是当我在show 方法中打印this.a(System.out.println(this.a))(在子类中重写)时,show 方法打印this.a (System.out.println(this.a)),它打印20,我很困惑。我认为结果应该是一样的。 可以看到输出如下图:

20
10

提前致谢!

【问题讨论】:

  • class A() ,class 周围没有()
  • 是的,我已经修改过了。

标签: java polymorphism


【解决方案1】:

我相信多态性的最佳实践不是重写变量,因为它会导致致命错误。如果您的问题是关于“多态性:操作方法”的,这个答案可能会有所帮助:

    //create class A, as you did:
    public class A {
        public int a; //note that we do not initialize the value here
        public void show() {
    
        }
    }

    //extend class B from class A, as you did:
    public class B extends A {
        public int b; //note that we only need to declare variable b

        @Override
        public void show() {
            System.out.println(this.a);
        }
    }

    //in the main class:
    public static void main(String[] args) {
        B a = new B();
        a.a = 20;
        a.b = 10;
        a.show();
    }

【讨论】:

    【解决方案2】:

    在java中只有方法被覆盖,变量没有。因此,父类的变量不会被子类的变量覆盖。这是Java中的设计决策。其中一个问题是父类方法可以执行而不用担心子类变量......即它有助于not breaking parent classes code...

    一个例子如下:

    public class Parent {
      String someVar; // note this: it is "String" type
      String getSomeVar() {
      }
    }
    
    public class Child extends Parent {
      int someVar; // same name but different type, this would break the code if
      // java permit "variable overriding" feature
    }
    

    你可以清楚地看到父母的类型和孩子的类型是不同的。我想,你现在可以理解为什么变量覆盖会很危险了……

    更新:

    @helloWorld,看了你最后的评论,看来你误解了overriding的想法。

    特别是,我为您准备了一个示例。用 cmets 阅读以下代码:

    class A {
        public int a = 10;
    
        public void show () {
            System.out.println("Inside A: " + this.a);
        }
    }
    
    class B extends A {
        public int a = 20;
        public int b = 10;
    
        @Override
        public void show() {
            System.out.println("Inside B: " + this.a);
        }
    }
    
    B b = new B();
    A a = b;
    
    b.show(); // prints "Inside B: 20", it should print "20", so it's okay
    a.show(); // prints "Inside B: 20", so, method in 'A' is overrided by class 'B', cause, in normal definition it should print "10"
    
    System.out.println("value of b.a: " + b.a); // prints "value of b.a: 20", it should print '20', so it's okay
    System.out.println("value of a.a: " + a.a); // prints "value of a.a: 10", it is not overrided by class 'B', but notice 'a.show()' method was overrided
    

    所以,我想,你已经明白了,覆盖意味着:当 parent/super class's reference 使用 something(a method/variable) 时,但在 parent/super 类的 particular method/variable 的实现存在时获得 child class's 中定义的行为,是称为覆盖...

    您也可以阅读this

    关于this:

    this 绑定到an object。它总是习惯于access,只有那个特定的class's scope,即在那个class中声明的variables/methods。因此,要在child 中访问parent,您需要使用super

    【讨论】:

    • 我知道只有方法被覆盖,而不是java中的变量。换句话说,我认为A类中的变量a与B中的变量a无关。但是当我使用方法显示时(@987654342 @) 在main中,我认为'this'应该是对父类A的对象a的引用。所以这里应该打印10而不是20。
    • @helloWorld,不,由于方法被覆盖,传递的this 将使用Ba 变量...但当然你已经得到它...你可以使用super 访问Aa 变量...希望它能解决问题...
    • @reyad 非常感谢。我大概明白你的意思了,但我还是有点糊涂。因为在A a = new B(),我认为a 应该在A 类中使用变量a 而不是在B类。在main方法中,您可以看到System.out.println(a.a)将打印10(public int a = 10在a类中)。
    • @helloWorld,告诉我what is this pointer...哪个对象this指针目标...在覆盖的方法范围this指针目标childthis只存在于non-static 方法...所以,a 可以转换为 A 但它是使用 B 创建的...这就是 java 解决在 parent scopechild scope 中定位正确变量的问题...这就是 java 的工作原理...现在我们无法改变它...这是 java 的哲学...它是 java 所做的...:D
    • ,嗯,再次感谢。也许我使用的方式违反了java的哲学,我想我应该放弃避免不必要麻烦的方式。
    猜你喜欢
    • 1970-01-01
    • 2011-01-10
    • 2021-11-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-21
    • 1970-01-01
    相关资源
    最近更新 更多