【问题标题】:Forcing a subclass to provide an initialization method强制子类提供初始化方法
【发布时间】:2018-04-01 06:40:40
【问题描述】:

提供一个抽象方法来帮助开发者在超类构造函数中初始化一个复杂的对象是一个好习惯吗?

考虑以下类:

// Parent class
abstract public class A() {
    protected Person[] people;

    public A(Person[] people) {
        this.people = people;
    }

    abstract protected Person[] initPeople();
}

// Child class
public class B extends A {
    public B() {
        super(initPeople());
    }

    @Override
    protected Person[] initPeople() {
        return new Person[] {
            new Person("James"),
            new Person("Mary"),
            new Person("Elizabeth")
        };
    }
}

如果没有initPeople 方法,子类的开发者可能会自己添加它,因为创建people 对象需要几行代码。

有没有更好的方法呢?谢谢!

【问题讨论】:

  • 是的:只需删除那个抽象方法,让子类决定它如何调用超类的构造函数。
  • 如果在超类中添加抽象,子类必须覆盖它。顺便说一句,initPeople 方法必须返回Person[]
  • 首先,您的代码不起作用,initPeople() 方法是无效的,但您正在返回无效。 @Override protected Person[] initPeople() { return new Person[] { new Person("James"), new Person("Mary"), new Person("Elizabeth") }
  • @Raedwald 除非我错过了什么,否则 OP 会明确询问 “有没有更好的方法来做到这一点”,这表明问题不在于调用 abstract 方法构造函数但要求一种强制子类提供初始化方法的方法?在构造函数中调用abstract 方法是OP 可以想到的解决方案之一,但这不是真正的问题吗?
  • @Raedwald 这与将其标记为重复有什么关系?一个坏主意(我不同意这是一个坏主意,但那是题外话)不会让它成为重复的候选者,我确定?

标签: java oop types constructor abstract


【解决方案1】:

这种方法的主要问题是,即使需要子类来实现initPeople 方法,也没有什么强制子类在构造函数中调用它。

更好的方法是使用Template 设计模式:

public abstract class A 
{
    protected Person[] people;

    public final void execute() 
    {
         initPeople();
         performOperations();
    } 
    protected abstract void initPeople();
    protected abstract void performOperations();
}

【讨论】:

  • 谢谢你的想法。我有一个问题:在A的构造函数中调用execute()安全吗?
  • 不建议这样做。构造函数的目的是初始化一个对象,而不是调用对数据执行操作的方法。这里的想法是,在实例化A 的子类之后,客户端将调用execute 方法。 execute方法会先通过initPeople初始化person数组,然后调用performOperations。代码的结构方式,子类总是必须提供一种初始化 person 的方法,然后提供一种对其执行一些操作的方法。
  • 为什么选择RuntimeException 而不是UnsupportedOperationException
  • @FrankK 根据定义,UnsupportedOperationException 表示不支持的可选操作;但是,在这种特殊情况下,initPeopleexecute 方法正确性的核心。如果people 数组未初始化,则没有一个子类可以正确完成工作。
  • 在这种情况下,为什么不把它抽象化呢?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-26
  • 1970-01-01
  • 1970-01-01
  • 2020-02-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多