天真的继承问题 - Java

时间:2011-09-10 02:30:41

标签: java inheritance arraylist

G'day人,

通过提出这样一个天真的问题,我感到很尴尬。但我无法理解一件事, 我有这样的继承结构,

enter image description here

B扩展A,我写的代码如下,

A类

public class A{
    private int pos = 0;
    public A(){
        this.pos = 12;
    }
    public int getPos(){
        return this.pos;
    }
}

B类

public class B extends A{
    int spec = 15;
    public B(){
        super();
    }
    public int getSpec(){
        return this.spec;
    }
}

我还有一个课程要测试,这会让我们回答我的问题。

班级考试

import java.util.*;
public class Test{
    public static void main(String[] args){
        B a = new B();
        ArrayList<A> c = new ArrayList<A>();
        c.add(a);
        System.out.println(c.get(0).getPos());
        System.out.println(c.get(0).getSpec());
    }
}

问题:现在我正在创建一个B实例,这意味着我可以访问我父类的方法getPos()和B自己的方法getSpec()。但是如果我创建一个类型为A的ArrayList(... B也是类型A,因为它扩展了A ...)并添加了我的B实例,它就失去了访问它自己的方法的能力。我究竟做错了什么? ArrayList实现是否在内部将我的B转换为A?


  

注意:我对继承的基本了解是父无法访问   孩子的方法,除了他们受到保护。但是孩子可以访问他们的   父类的方法。

3 个答案:

答案 0 :(得分:4)

不涉及任何演员。你正在做的事情与此无异:

A bAsA = new B():

虽然bAsA引用的对象确实是B对象,但它由A变量保存,因此只有A方法可用(除非您明确地将其转换为B变量)。

由于您的ArrayList是A的ArrayList,因此ArrayList中的每个项都被视为A变量,只有A方法可用。

答案 1 :(得分:4)

  

ArrayList实现是否在内部将我的B转换为A?

没有。没有“内部铸造”。 你,程序员告诉编译器它是A的列表。

您已将{{1>} List 宣布为<{1}},您可以将其视为List<A>的列表。由于所有A均为B,因此您可以将A添加到B。但是,在检索时,您只能保证返回List<A>,而不是A - 因为它是B,请记住 - 因此编译器会处理所有内容作为List<A>从列表中出来,即使(在运行时)它是A的实例。

答案 2 :(得分:3)

@Matt Ball@Hovercraft Full Of Eels提供的答案外,您还可以通过声明<实施 em> subclass 作为超类中的 抽象 方法。

public abstract class A{
    .
    .
    public abstract int getSpec();
}

修改 -

@Kublai Khan所述,有必要将超类设为 抽象 类。