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

新手上路,请多包涵

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

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

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

原文由 Paul 发布,翻译遵循 CC BY-SA 4.0 许可协议

阅读 371
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 模式,并将该接口的一个实例传递给不再抽象的基类。用术语来说,这是使用组合而不是继承(您已经从两个对象(一个聚合器和一个加法器)中组合了一个加法聚合器)。

原文由 yshavit 发布,翻译遵循 CC BY-SA 3.0 许可协议

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

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

但是, print() 对于每台打印机都不同,而 getSystemResource() 对于所有三台打印机都保持不变。你还有另外一个顾虑,你想应用多态。

由于 getSystemResource() 对于所有三台打印机都是相同的,您可以将其推送到要实现的超类,并让子类实现 print() 。在 Java 中,这是通过在超类中制作 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();
}

原文由 OCB 发布,翻译遵循 CC BY-SA 4.0 许可协议

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题
logo
Stack Overflow 翻译
子站问答
访问
宣传栏