抽象类构造函数参数与最终数据抽象方法

时间:2020-05-01 00:47:47

标签: java initialization abstract-class final

使用抽象类构造函数与将最终数据传递给抽象类的抽象方法的利弊是什么?

通过构造函数传递:

public abstract class MyAbstractClass<T> {
  private final String type;
  private final Function<String, T> factoryFn;

  protected MyAbstractClass(String type, Function<String, T> factoryFn) {
    this.type = type;
    this.factoryFn = factoryFn;
  }

  public T doSomething(String value) { ... }
}

通过抽象方法传递:

public abstract class MyAbstractClass<T> {
  abstract String getType();

  abstract T getFactoryFn(String value);

  public T doSomething(String value) { ... }
}

我知道抽象方法可能会被滥用,因为它并不强制总是返回相同的值。

但是除此之外,这仅仅是个人喜好问题,还是使用一个相对于另一个的任何真正(不利)优势?

1 个答案:

答案 0 :(得分:1)

希望我能正确理解您的问题。

通常,当将类的属性始终保留在字段中时,使用抽象构造函数更为简洁。例如,考虑以下两种情况....

// Scenario 1:
abstract class AClass {
    final int field;
    public AClass(int f) {
        field = f;
    }

    public int getField() {
        return field;
    }
}

class Class1 extends AClass {
    public Class1(int f) {
        super(f);
    }

    // Class Unique Code...
}

class Class2 extends AClass {
    public Class2(int f) {
        super(f);
    }

    // Class Unique Code...
}


// Scenario 2:
abstract class AClass {
    public abstract int getField();
}

class Class1 extends AClass {
    final int field;

    public Class1(int f) {
        field = f;
    }


    @Override
    public int getField() {
        return field;
    }

    // Class Unique Code...
}


class Class2 extends AClass {
    final int field;

    public Class2(int f) {
        field = f;
    }


    @Override
    public int getField() {
        return field;
    }

    // Class Unique Code...
}

场景1较短,因为field的getter逻辑仅需要指定一次。而在场景2中,两个子类都必须重写getter逻辑。我发现方案2是多余的...为什么在可以利用Java继承发挥自己的优势时为什么要编写两次相同的代码。

最后一点,除非完全必要,否则我通常不在字段中保留函数。每当字段中有函数时,通常是可以应用抽象函数的信号。

这是您的原始代码,并应用了我的建议...

public abstract class MyAbstractClass<T> {
    private final String type;

    protected MyAbstractClass(String t) {
        type = t;
    }

    protected abstract T applyFactoryFunction(String value);

    public T doSomething(String value) { ... }
}

希望这对您有所帮助!

相关问题