3 回答
TA贡献1828条经验 获得超3个赞
无法覆盖字段。在你的情况下,儿子的字段只是向爸爸隐藏字段:
在类中,与超类中的字段同名的字段将隐藏超类的字段,即使它们的类型不同也是如此。在子类中,超类中的字段不能通过其简单名称引用。[...]一般来说,我们不建议隐藏字段,因为这会使代码难以阅读。
将函数声明为类,因此它只能看到 null 的实例形式。您可以从儿子实例访问爸爸的。GetHome
Dad
home
Dad
home
super.home
您可以提取超类或接口。
interface HasHome {
Building getHome();
}
class Dad implements HasHome {
protected Building home;
public Dad() {
this.home = new Building();
}
@Override
public Building getHome(){
return this.home;
}
}
class Son implements HasHome { // Or extends Dad
protected Shack home;
public Son () {
super();
this.home = new Shack();
}
@Override
public Shack getHome() {
return home;
}
}
选择哪种方式还有另一个问题。此外,超类型可以是通用的,如@Lorelorelore所示。
TA贡献1785条经验 获得超4个赞
也许你应该用泛型重构这两个类:
抽象超类:
public abstract class Person<T extends Building> {
protected T home;
public T getHome(){
return this.home;
}
}
爸爸班:
public class Dad extends Person<Building> {
public Dad() {
home = new Building();
}
}
儿子类:
public class Son extends Person<Shack> {
public Son () {
home = new Shack();
}
}
您可以通过简单的测试检查该字段是否具有正确的类型(并且不为 null):home
public class SonAndDadTest {
@Test
public void sonTest(){
Son son = new Son();
Assert.assertNotNull(son.getHome());
Assert.assertEquals(son.getHome().getClass(), Shack.class);
}
@Test
public void dadTest(){
Dad dad = new Dad();
Assert.assertNotNull(dad.getHome());
Assert.assertEquals(dad.getHome().getClass(), Building.class);
}
}
TA贡献1757条经验 获得超8个赞
不应在子类中重新声明具有相同名称的字段。这是因为字段是隐藏的,而不是被覆盖的。
编译器不会抱怨这一点,但在这种情况下有两个变量。 未由 中的构造函数赋值。因此,在本例中将返回,这是因为只知道 .Dad.home
Son
new Son().getHome()
null
getHome()
Dad.home
从您所在的位置开始,最好的方法是从 中删除属性,更好的是,使用构造函数参数将其放入并从子类中传递其值。home
Son
private
Dad
添加回答
举报