【问题标题】:use abstract superclass' constructor by default?默认使用抽象超类的构造函数?
【发布时间】:2018-09-16 09:49:24
【问题描述】:

这样的可能吗

abstract class AbstractSuperClass {
  private Entity entity;

  public AbstractSuperClass(Entity entity) {
    this.entity = entity;
  }

  public abstract void operate();
}

public class SubClass extends AbstractSuperClass {
  public void operate() {
    this.entity.doVoidMethod(); // is this.entity defined in instances of SubClass ?
  }
}

// ... somewhere else

Entity instantiatedEntity = new Entity();
SubClass instance = new SubClass(instantiatedEntity);
instance.operate(); // does this call this.entity.doVoidMethod() inside of instance?

我希望能够跳过在我正在编写的抽象类的子类中编写自己的构造函数。每个子类中的所有构造函数都是相同的。

如果我跳过为抽象类的子类编写构造函数(这甚至允许吗?)是否默认使用抽象类的构造函数?

【问题讨论】:

  • 仅当它没有参数并且可以访问时。
  • @EJP “可访问”是什么意思?并且构造函数必须有一个参数
  • 普通 Java 源代码需要为每个调用 super 构造函数的子类包含一个构造函数,并将 Entity 传递给它。但是,您可以使用注释自动生成它,类似于 Lombok 的那些。
  • @DodgyCodeException 我如何使用注释来做到这一点? (我没听说过龙目岛)
  • 这是在回复评论时无法回答的问题。关于如何做到这一点的整本书都写了。

标签: java oop inheritance abstract-class superclass


【解决方案1】:

首先,如果您不定义构造函数,则考虑使用不带参数的默认构造函数。
换句话说,如果您想使用new SubClass(instantiatedEntity);,您必须在SubClass 中定义构造函数,该构造函数采用Entity 类型的单个参数。
换句话说,如果你想传递参数,你不能跳过编写自己的构造函数。

其次,在您的SubClass 中,您不能调用this.entity.doVoidMethod();。这是因为entity 属性在基类中是私有的,因此子类无法访问。

此外,在AbstractSuperClass 中,您定义了public abstract Operate();。你的意思可能是public abstract void operate();。子类中也有类似的错误。

【讨论】:

  • 我需要在AbstractSuperClass 内部的entity 上进行什么设置,以确保我可以从SubClass 访问它?
  • 您要么将属性设为受保护或公开,要么创建一个 getter(一种返回属性的方法)。
【解决方案2】:

我希望能够跳过在我正在编写的抽象类的子类中编写自己的构造函数。每个子类中的所有构造函数都是相同的。

你不能。 Java 中不继承构造函数:

Java Constructor Inheritance

唯一的准例外是default constructor。然而,严格来说,它不是继承。如果没有构造函数,则添加默认构造函数,它将调用super()

如果我跳过为抽象类的子类编写构造函数(这是否允许?)是否默认使用抽象类的构造函数?

没有。超类的构造函数既不被继承也不被复制。

【讨论】:

  • 默认构造函数的想法对于不强制定义构造函数很有用,因此如果父类有一个没有参数的构造函数,则可能是部分答案。但这是一个受限的解决方案。
【解决方案3】:

根据您上面的代码,您使用的子类是从抽象类扩展而来的。

abstract class A{
 A(){
  //todo: some work
 }
 abstract methodA();
 methodB(){
  //todo:something: implementation within the abstract class.
 }
}
class B extends A{
 B(){
 super(this);
  }

}

我相信使用抽象构造函数你会使用 super 关键字。

【讨论】:

  • OP 说他想跳过在子类中编写构造函数;因为它们都是相同的。
  • 是的,我只是不知道他会如何实现,因为每个类都需要默认实例化。但我愿意被纠正。
  • @MuyindaRogers 感谢您的努力,但如果您不知道如何实现所要求的内容,也许最好不要回答?
  • @lexicore 我认为这是一种粗鲁的方式,你会驱赶人们表达并接受纠正。这不是投反对票和不给予任何回报的问题。
  • 我是投反对票的人。原因是您根本没有回答问题。您不能简单地编写一个替换构造函数的方法(特别是如果您不调用它),super(this) 在这里没有意义(并且不会编译)。当然,没有任何解释,这无济于事。
【解决方案4】:

一些想法(1)你应该让实体“受保护”而不是“私有”——这就是你如何让它在子类中可用,(2)它有助于使用可以被继承的访问器方法(getter/setter)子类与非默认构造函数不同,(3)操作方法需要返回类型(我在下面使用 void),(4)操作方法需要相同的签名(类型敏感的名称和参数类型)才能覆盖(5)它使用 @Override 注释被覆盖的方法是一种很好的做法。

public abstract class AbstractSuperClass {
  protected Entity entity;

  public AbstractSuperClass() {
  }

  public AbstractSuperClass(Entity entity) {
    this.entity = entity;
  }

  public setEntity(Entity entity) {
    this.entity = entity;
  }

  public abstract void operate();
}

public class SubClass extends AbstractSuperClass {
  @Override
  public void operate() {
    this.entity.doVoidMethod(); // protected entity is available in subclass
  }
}

// ... somewhere else
Entity instantiatedEntity = new Entity();
SubClass instance = new SubClass(); // default constructor
instance.setEntity(instantiatedEntity); // inherited method
instance.operate(); // yes calls entity.doVoidMethod()

【讨论】:

  • 它无法编译 ... SubClass 找不到默认构造函数 AbsthractSuperClass 没有参数的构造函数。还有很多不必要的信息。
  • 好点。我在父类中添加了一个默认构造函数,以便子类可以找到它。额外的 cmets 只是原始海报的清晰度。
  • 投了反对票,因为这种 setter 会使代码更容易出错且不易维护。
猜你喜欢
  • 2014-04-30
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-04
  • 1970-01-01
  • 1970-01-01
  • 2015-12-10
  • 1970-01-01
相关资源
最近更新 更多