与实例变量的多态性 [英] Polymorphism with instance variables

查看:115
本文介绍了与实例变量的多态性的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

以下是我写的三个课程:

Here are three classes that I wrote:

public class Shape {

    public int x = 0;

    public void getArea() {
        System.out.println("I don't know my area!");
    }

    public String toString() {
        return "I am a shape!";
    }

    public int getX() {
        return x;
    }
}

public class Rectangle extends Shape {

    public int x = 1;

    public int getX() {
        return x;
    }

    public void getArea() {
        System.out.println("L*W");
    }

    public String toString() {
        return "I am a rectangle!";
    }
}

public class Tester {

    public static void main(String[] args) {
        Shape s = new Shape();
        Rectangle r = new Rectangle();

        System.out.println(r);
        System.out.println(r.x + "\n");

        s = r;
        System.out.println(s);
        s.getArea();
        System.out.println(s.x);
        System.out.println(s.getX());
    }
}

Tester类的main方法的输出是:

The output from the main method of the Tester class is:


I am a rectangle!

1

I am a rectangle!

L*W

0

1

为什么sx返回0而不是1?因为不是变量的当前实例,而是一个Rectangle,并且该类也声明了相同的实例变量,或者Rectangle类中的变量不会覆盖Shape类中的前一个公共x变量,就像它对getX()一样。因此,矩形类中的方法返回1?

Why does s.x return 0 and not 1? As isn't the current instance of the variable a Rectangle and that class also has that same instance variable declared, or does the variable in the Rectangle class not override the previous public x variable in the Shape class as it does to the getX() method in the rectangle class thus returning 1?

同样作为一般规则,超类只有在该类中声明为子类方法时,才能访问其子类方法的实现。好?这是因为编译器会看到具有相同签名的相同数量的方法在Shape类中(具有重写的Rectangle实现)并接受那些作为有效的Shape方法吗?

Also as a general rule the superclass has access to the implementation of the its subclasses methods only if they are declared in that class as well? Is this because the compiler will see that the same amount of methods with the same signature are in the "Shape" class (with overridden Rectangle implementations) and accept those as valid Shape methods?

提前致谢,

推荐答案

Java中的字段没有多态性。然而,继承。你已经有效地完成了在Rectangle类中创建两个具有相同名称的字段。该字段的名称有效:

There is no polymorphism for fields in Java. There is however, inheritance. What you've effectively done is create two fields in your Rectangle class, with the same name. The names of the field are, effectively:

public class Rectangle {
    public int Shape.x;
    public int Rectangle.x;
}

以上并不代表有效的Java,它只是一个例子字段在类中的作用域

在Rectangle类的整个范围内,同名的超类字段为 hidden 的。因此,只要您在类中引用简单名称 x 或作用域名 this.x ,就会引用到 Rectangle 中定义的字段。您实际上也可以访问超类字段,其范围名称为 super.x

Within the entire scope of the Rectangle class, the superclass field of the same name is hidden. So anytime you reference the simple name x, or the scoped name this.x, within the class, you are referring to the field that is defined in Rectangle. You can actually access the superclass field as well, with the scoped name super.x.

现在,从外部在该类中,访问字段的规则略有不同。范围将由引用该字段的类的 编译 时间类型确定。所以在你的代码中:

Now, from outside of the class, the rules for which field is being accessed is slightly different. The scope will be determined by the compile time type of the class that the field is being referenced from. So in your code:

Shape s = new Shape();
Rectangle r = new Rectangle();

s = r;
System.out.println(s.x);

输出为 0 因为编译时间类型 s Shape (不是 Rectangle )。执行此操作时,您可以观察到此行为的更改:

The output is 0 because the compile time type of s is Shape (not Rectangle). You can observe a change in this behavior when you do this:

Shape s = new Shape();
Rectangle r = new Rectangle();

s = r;
System.out.println(((Rectangle)s).x);

Presto!您的输出现在是 1 ,因为编译器发现您已将字段访问限定为 Rectangle

Presto! Your output is now 1, because the compiler sees that you've scoped the field access to Rectangle.

要压缩可见性规则:

您可以在 JLS,第8.3.3.2节

这篇关于与实例变量的多态性的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆