Java覆盖引用

时间:2014-02-20 15:01:41

标签: java reference overwrite

所以这是非常基本但我无法掌握它。我们假设我们有两个类A,B(继承自A):

  class A {
        public void m() {System.out.println("AAA");}
    }
  class B extends A {
        public void m() {System.out.println("BBB"); }
    }

我们的主要课程:

class Test{
    public static void main(String [] args){
        A a=new A(); B b=new B(); A x;
        x=a; x.m(); // "AAA"
        x=b; x.m(); // "BBB"

        a=b; a.m();   // "BBB"
        b=a; b.m();   // ERROR
    }}

在我的理解中,'x'是对A类型的null的引用,因为没有创建对象。当我输入x = a;对null的引用现在指向A的实例。如果我调用x.m(),则打印“AAA”..同名x = b; x.n(); “BBB”;

但是如果我创建一个实例A,其中'a'是对它的引用,并说b = a;它说错误。找到了必需的B。

我认为'b'的引用被引用'a'覆盖,如果我现在调用b.m();它给了我“AAA”,因为它现在指向A的实例。虽然a = b;用a.m()打印“BBB”

为什么?

3 个答案:

答案 0 :(得分:4)

首先,我只是在你的班级名称中添加一些字符:

  class Animal {
        public void m() {System.out.println("AAA");}
  }
  class Bee extends Animal {
        public void m() {System.out.println("BBB"); }
  }

class Test{
public static void main(String [] args){
    Animal a=new Animal();
    Bee b=new Bee();
    Animal x;

    x=a; x.m(); // "AAA" a is an animal
    x=b; x.m(); // "BBB" b is a Bee, so it's an Animal

    a=b; a.m();   // "BBB" A Bee is an Animal
    b=a; b.m();   // ERROR An Animal is a Bee? What if it's a Cat?
}}

如果仍然不清楚,让我们创建一个类:

class Cat extends Animal{
    public void m() {System.out.println("CAT"); }
    public void foo() {System.out.println("FOO"); }
};

您可以在Animal a=new Animal();之前更改上一个代码Animal a= new Cat();,然后您会看到b=a不正确,因为蜜蜂不是猫。

更新:我在Cat类中添加了两个方法。让我们看看它是如何工作的:

// This is the obvious part:
Cat c= new Cat();
c.m(); // "CAT"
c.foo(); // "FOO"

// Not so obvious
Animal a2= new Cat(); // a Cat is an animal
a2.m(); // "CAT"
a2.foo(); //Won't compile: ERROR

这里发生了什么?猫是一种动物,这确保它具有方法m。该方法的行为由实例本身定义。 a2是一个指向Cat实例的变量,但我们只能调用Animal定义的方法,因为a2也可能是任何其他动物,我们不知道它可能有哪些方法。是的,在这种情况下我们知道它是一只猫,但是我们说我们有这种方法:

public Animal createAnAnimal() {
    if (Random.nextBoolean()) {
        return new Cat();
    } else {
        return new Bee();
    }
}

无论如何,你应该阅读有关继承和接口的内容,这会增加这些内容的复杂性。

答案 1 :(得分:2)

我认为你的问题是,你有错误的观点。

您认为,如果您设置a = b,则a将为B类型!但它a仍为A类型,并且引用了类B的实例。

这就是为什么你不能将类A的值设置为B类型的变量!

A a = new A();
B b = new B();
A x;

x = a; // x is of type A and has now a reference to an instance of type A
x = b; // x is of type A and has now a reference to an instance of type B

a = b; // a is of type A and has now a reference to an instance of type B
b = a; // b is of type B and you can't set a reference to a variable of type A

答案 2 :(得分:0)

想象一下,你有另一个班级C:

class C extends A {
   public void m() {System.out.println("CCC"); }
}

然后您的代码可以修改:

A c = new C();
B b = c;

这显然不正确,因此错误。