使用抽象方法有什么意义?

2022-09-01 04:30:08

使用“抽象方法”有什么意义?抽象类不能实例化,但是抽象方法呢?他们只是在这里说“你必须实现我”,如果我们忘记了他们,编译器就会抛出错误吗?

这是否意味着别的什么?我还读到了一些关于“我们不必重写相同的代码”的内容,但是在抽象类中,我们只“声明”抽象方法,因此我们将不得不重写子类中的代码。

你能帮我多理解一下吗?我检查了有关“抽象类/方法”的其他主题,但我没有找到答案。


答案 1

假设您有三台打印机,您需要为 、 、 和 编写驱动程序。LexmarkCanonHP

所有三台打印机都将具有 和 方法。print()getSystemResource()

但是,对于每台打印机,将有所不同,并且对于所有三台打印机都保持不变。你还有另一个问题,你想应用多态性。print()getSystemResource()

由于所有三台打印机都是相同的,因此您可以将其推送到要实现的超类,并让子类实现。在Java中,这是通过在超类中进行抽象来完成的。注意:在类中使方法抽象时,类本身也需要是抽象的。getSystemResource()print()print()

public abstract class Printer{
  public void getSystemResource(){
     // real implementation of getting system resources
  }
  
  public abstract void print();
}

public class Canon extends Printer{
  public void print(){
    // here you will provide the implementation of print pertaining to Canon
  }
}

public class HP extends Printer{
  public void print(){
    // here you will provide the implementation of print pertaining to HP
  }
}

public class Lexmark extends Printer{
  public void print(){
    // here you will provide the implementation of print pertaining to Lexmark
  }
}

请注意,HP、Canon 和 Lexmark 类不提供 的实现。getSystemResource()

最后,在主类中,您可以执行以下操作:

public static void main(String args[]){
  Printer printer = new HP();
  printer.getSystemResource();
  printer.print();
}

答案 2

除了提醒你必须实现它之外,最大的优点是,任何通过抽象类类型(包括在抽象类本身中)引用对象的人都可以使用该方法。this

例如,假设我们有一个类负责获取状态并以某种方式操纵它。抽象类将负责获取输入,将其转换为(例如)并以某种方式将该值与前一个值组合 - “某种方式”是抽象方法。抽象类可能如下所示:long

public abstract class StateAccumulator {
    protected abstract long accumulate(long oldState, long newState);

    public handleInput(SomeInputObject input) {
        long inputLong = input.getLong();
        state = accumulate(state, inputLong);
    }

    private long state = SOME_INITIAL_STATE;
}

现在,您可以定义一个加法累加器:

public class AdditionAccumulator extends StateAccumulator {
    @Override
    protected long accumulate(long oldState, long newState) {
        return oldState + newState;
    }
}

如果没有该抽象方法,基类将无法说“以某种方式处理此状态”。但是,我们不想在基类中提供默认实现,因为它没有多大意义 - 您如何为“其他人将实现此”定义默认实现?

请注意,剥猫皮的方法不止一种。策略模式将涉及声明声明模式的接口,并将该接口的实例传递给不再抽象的基类。在行话术语中,这是使用组合而不是继承(您已经从两个对象(一个聚合器和一个加法器)中组成了一个加法聚合器)。accumulate


推荐