2017-04-24 128 views
25

我无法理解以下输出。Java继承字段

我不知道为什么输出是10,我觉得行A a = new B()创建B类的新实例,我想结果应该是20

class A { 
    int i = 10; 
} 

class B extends A { 
    int i = 20; 
} 

public class MainClass { 
    public static void main(String[] args) { 
     A a = new B(); 

     System.out.println(a.i); 
    } 
} 

为什么这个是这样的..请说明。

+11

你不重写值我在这里,你的影子 –

+2

看看这篇文章。 http://stackoverflow.com/questions/685300/is-there-a-way-to-override-class-variables-in-java –

+0

多态性不适用于字段,它为方法做的方式。你使用了一个'A'类型的变量来查找字段'i',所以你得到'A'类型的副本,而不是类型'B'中的副本。当你查看字段时,重要的是变量的类型,而不是对象的类。 –

回答

30

首先,看看Hiding Fields(强调)

在一类,具有相同的名称作为超一个字段的字段隐藏超类的领域,即使它们的类型不同

换句话说,这是不是“遗产”,因为你实际上隐藏A小号0123的iB背后“,并且您正在使用A的引用对象,因此您正在获取其字段。如果您确实B b = new B(),您会看到20,如预期。


如果您期望真正的覆盖,请尝试使用方法。

class A { 
    public int get() { 
     return 10; 
    } 
} 

class B extends A { 
    @Override 
    public int get() { 
     return 20; 
    } 
} 

A a = new B(); 
System.out.print(a.get()); // 20 

如果你真的想看到两者兼而有之,看到这个例子。

class A { 
    int i = 10; 
} 

class B extends A { 
    int i = 20; 

    @Override 
    public String toString() { 
     return String.format("super: %d; this: %d", super.i, this.i); 
    } 
} 

而且

A a = new B(); 
System.out.print(a); // super: 10; this: 20 
1

成员变量i已在class A中定义。

为了实现你在找什么,改变class B如下图所示:

class B extends A { 
    public B() { 
     i = 20; 
    } 
} 
20

在java中不能覆盖实例变量。您正在获得的输出是预期的。在Java中,您只能覆盖实例方法而不是实例变量。

如果您希望将20作为输出,您可以对这些实例变量使用getter方法。

class A { 
    int i = 10; 

    int getI() { 
     return i; 
    } 
} 

class B extends A { 
    int i = 20; 

    int getI() { 
     return i; 
    } 
} 

public class MainClass { 
    public static void main(String[] args) { 
     A a = new B(); 

     System.out.println(a.getI()); 
    } 
} 
10

多态性不适用于领域在Java.Evaluating变量作出决定在编译时所以总是基类的变量被访问。

4

因为您定义了两个变量:一个在子类B中,另一个在超类A中具有相同名称。

A a = new B(); 
a.i; // refers to A.i 

如果你投的AB,它将访问B.i

System.out.println(((B)a).i); 

我认为你需要使用1个变量:

class A { 
    int i; 

    public A() { 
     i = 10; 
    } 
} 

class B extends A { 
    public B() { 
     i = 20; 
    } 
} 

public class MainClass { 
    public static void main(String[] args) { 
     A a = new B(); 

     System.out.println(a.i); // will print 20 
}