在Java中覆盖类参数类型

问题描述 投票:0回答:3

是否可以覆盖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{
 (...)
}

显然,添加两个具有相同名称的parate并没有问题,但我不确定这两个参数是否“链接”在一起..

当我从getHome()对象调用Son函数时,它返回一个null对象。这是有道理的,因为Dad对象没有初始化的Building对象。即使Son有一个初始化Shack对象延伸Building类。 (我不知道我是否足够清楚......)

一个简单的解决方案是简单地用home对象初始化Shack,并在必要时在home中施放Shack。但我想知道是否有另一种方法可以做到这一点。

java parameters override
3个回答
1
投票

字段无法覆盖。在你的案例中,来自爸爸的qazxsw poi字段:

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

hiding函数声明为GetHome类,因此它只能看到Dad实例形式为home,它是null。您可以从Son实例访问爸爸的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所示。


1
投票

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

编译器不会抱怨这一点,但在这种情况下有两个变量。 another question不是由Dad.home的构造函数指定的。所以Son将在这个例子中返回new Son().getHome(),那是因为null只知道getHome()

从你所在的位置来看,最好的方法就是从Dad.home中删除home属性,更好的是,在Son中创建private并使用构造函数参数从子类中传递它的值。


1
投票

也许你应该用泛型重构这两个类:

抽象超类:

Dad

爸爸班:

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
© www.soinside.com 2019 - 2024. All rights reserved.