G'day人,
通过提出这样一个天真的问题,我感到很尴尬。但我无法理解一件事, 我有这样的继承结构,
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?
注意:我对继承的基本了解是父无法访问 孩子的方法,除了他们受到保护。但是孩子可以访问他们的 父类的方法。
答案 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所述,有必要将超类设为 抽象 类。