覆盖Java中的类参数类型

时间:2019-03-27 10:01:49

标签: java parameters override

是否可以在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()对象调用Son函数时,它返回一个空对象。这很有意义,因为Dad对象没有初始化的Building对象。即使Son具有初始化Shack类的初始化Building对象。 (我不知道我是否足够清楚...)

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

3 个答案:

答案 0 :(得分:1)

不能覆盖字段。在您儿子的情况下,爸爸的hiding字段是:

  

在一个类中,与该字段中的字段同名的字段   超类隐藏超类的字段,即使它们的类型是   不同。在子类中,超类中的字段不能为   以其简单名称引用。 [...]一般   讲,我们不建议隐藏字段,因为这会使代码变得困难   阅读。

已在GetHome类中声明了Dad函数,因此它只能看到home实例形式Dad,该实例为空。您可以从Son实例以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;
    }
}

another question种选择方式。而且,超类型可以是通用的,如@Lorelorelore所示。

答案 1 :(得分:1)

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

编译器不会对此抱怨,但是在这种情况下有两个变量。 Dad.home中的构造方法未分配Son。因此,在此示例中,new Son().getHome()将返回null,这是因为getHome()只知道Dad.home

在您所处的位置,最好的办法就是从home中删除Son属性,更好的是,在private中将其设为Dad,并从子类使用构造函数参数。

答案 2 :(得分:1)

也许您应该使用泛型来重构这两个类:

抽象超类:

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

}

您可以通过简单的测试来检查home字段的类型是否正确(并且也不为null):

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

}