为了账号安全,请及时绑定邮箱和手机立即绑定

在 Java 中重写类参数类型

在 Java 中重写类参数类型

慕斯王 2022-09-07 17:27:13
是否可以在 Java 中重写类参数?我很确定这是不可能的,但是...public class Dad {  protected Building home;  public Dad() {  }  public Building getHome(){     return this.home;  }}public class Son extends Dad {  protected Shack home;  public Son () {    super();    this.home = new Shack();  }}public Shack extends Building{ (...)}显然,添加两个同名的参数没有问题,但我不确定这两个参数是否“链接”在一起。当我从对象调用函数时,它返回一个空对象。这是有道理的,因为对象没有初始化的对象。即使有一个扩展类的初始化对象(我不知道我是否足够清楚...)getHome()SonDadBuildingSonShackBuilding一个简单的解决方案是简单地使用对象进行初始化,并在必要时强制转换。但我想知道是否有另一种方法可以做到这一点。homeShackhomeShack
查看完整描述

3 回答

?
子衿沉夜

TA贡献1828条经验 获得超3个赞

无法覆盖字段。在你的情况下,儿子的字段只是向爸爸隐藏字段:

在类中,与超类中的字段同名的字段将隐藏超类的字段,即使它们的类型不同也是如此。在子类中,超类中的字段不能通过其简单名称引用。[...]一般来说,我们不建议隐藏字段,因为这会使代码难以阅读。

将函数声明为类,因此它只能看到 null 的实例形式。您可以从儿子实例访问爸爸的。GetHomeDadhomeDadhomesuper.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所示。


查看完整回答
反对 回复 2022-09-07
?
九州编程

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);

    }


}


查看完整回答
反对 回复 2022-09-07
?
陪伴而非守候

TA贡献1757条经验 获得超8个赞

不应在子类中重新声明具有相同名称的字段。这是因为字段是隐藏的,而不是被覆盖的。

编译器不会抱怨这一点,但在这种情况下有两个变量。 未由 中的构造函数赋值。因此,在本例中将返回,这是因为只知道 .Dad.homeSonnew Son().getHome()nullgetHome()Dad.home

从您所在的位置开始,最好的方法是从 中删除属性,更好的是,使用构造函数参数将其放入并从子类中传递其值。homeSonprivateDad


查看完整回答
反对 回复 2022-09-07
  • 3 回答
  • 0 关注
  • 102 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信