2017-04-01 63 views
3

我有一个超类名为TestSuper如何从子类中获取数据字段而不是超类?

public class TestSuper { 
    int a = 0; 
} 

,我有2名为TestSub子类和TestSub2,在我的主类扩展TestSuper

public class TestSub extends TestSuper{ 
    int a=1; 
} 

public class TestSub2 extends TestSuper{ 
    int a=2; 
} 

我创建了一个发生在一个类型TestSuper的方法并返回它的一个值,并在主屏幕上显示它

public class Main { 
public static void main(String[] args){ 

    System.out.println(test(new TestSub())+" "+test(new TestSub2())); 
} 
public static int test(TestSuper b){ 
    return b.a; 
} 
} 

但输出是“0 0”而不是“1 2”,我该怎么办?

+2

您只能覆盖子类中的方法。你不能覆盖字段。 –

+0

只需在你的子类'TestSub(){a = 1;}' – Maraboc

回答

3

您需要将参考转换为说出您想要的参考。

public static int test(TestSuper b){ 
    return b instanceof TestSub ? ((TestSub) b).a : 
      b instanceof TestSub2 ? ((TestSub2) b).a : 
      b.a; 
} 

如果这似乎是不必要的复杂,那是。你应该使用多态。

public class TestSuper { 
    int a = 0; 
    public int getA() { return a; } 
} 

public class TestSub extends TestSuper { 
    int a = 1; 
    public int getA() { return a; } 
} 

public class TestSub2 extends TestSuper { 
    int a = 2; 
    public int getA() { return a; } 
} 

public static int test(TestSuper b) { 
    return b.getA(); 
} 
+0

添加一个构造,所以如果你重新定义了子类中的字段并将子类的实例转换为超类,那么返回值就是超类的值,但是如果你通过方法或getter来请求值,那么返回值就是subClass的值!不知道,现在我想知道为什么? – Cherif

+0

@Charif非静态方法遵循继承,字段不遵守。 –

+1

现在我想像和包含两个字段具有相同名称但不同值的子类的实例。是发生了什么 – Cherif

0

你可以看看背后的理论,然后做唯一合理的事情 - 忘记编写这样的代码。

在良好的面向对象中,你认为你的领域是你的“秘密”内部实现的一部分。您不要在超类上下文中使用子类的字段。期。

对于在超类中创建一个保护字段并在子类中使用它,你甚至非常保守。

0

当你调用测试方法是这样的:

test(new TestSub())+" "+test(new TestSub2()) 

您使用上溯造型。上传分离接口和对象的实现。但是,为了分离接口和实现并在多态中实现真正的实现,您必须使用多态结构。实例变量不是多态的。正因为如此,实际上你会调用TestSuper类中的一个变量。

只有实例方法是多态的。