Pau*_*aul 31 java abstract-class
使用"抽象方法"有什么意义?抽象类无法实例化,但抽象方法呢?他们只是在这里说"你必须实现我",如果我们忘记它们,编译器会抛出错误吗?
这是否意味着别的什么?我还读到了一些关于"我们不必重写相同代码"的内容,但在抽象类中,我们只"声明"抽象方法,因此我们必须重写子类中的代码.
你能帮我理解一下吗?我检查了关于"抽象类/方法"的其他主题,但我没有找到答案.
Oh *_*oon 26
说你有,你就需要编写一个驱动程序,一个三台打印机Lexmark,Canon和HP.
所有三台打印机都将拥有print()和getSystemResource()方法.
但是,print()每台打印机只会有所不同.getSystemResource()在三台打印机中保持不变.您还有另一个问题,您想应用多态.
因此getSystemResource(),对于所有三个打印机来说都是相同的,所以这可以推送到超类来实现,在Java中,这可以通过在超类中进行抽象,并在超类中创建方法抽象来完成,班级本身也需要抽象.
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
  }
}
Run Code Online (Sandbox Code Playgroud)
请注意,HP,Canon和Lexmark类不提供实现getSystemResource().
最后,在您的主类中,您可以执行以下操作:
public static void main(String args[]){
  Printer printer = new HP();
  printer.getSystemResource();
  printer.print();
}
Run Code Online (Sandbox Code Playgroud)
        ysh*_*vit 16
除了提示你必须实现它之外,最大的好处是任何通过其抽象类类型(包括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;
}
Run Code Online (Sandbox Code Playgroud)
现在您可以定义一个加法累加器:
public class AdditionAccumulator extends StateAccumulator {
    @Override
    protected long accumulate(long oldState, long newState) {
        return oldState + newState;
    }
}
Run Code Online (Sandbox Code Playgroud)
如果没有这种抽象方法,基类就无法说"以某种方式处理这种状态".但是,我们不希望在基类中提供默认实现,因为它并不意味着什么 - 如何定义"其他人将实现此"的默认实现?
请注意,皮肤猫的方法不止一种.该策略模式将涉及声明声明的接口accumulate模式,并通过该接口的实例到不再视为抽象基类.在术语方面,那是使用组合而不是继承(你已经用两个对象,一个聚合器和一个加法器组成了一个加法聚合器).
抽象类是包含一个或多个抽象方法的类。抽象方法是已声明但不包含实现的方法。抽象类不能被实例化,并且需要子类提供抽象方法的实现。让我们看一个抽象类和抽象方法的示例。
\n\n假设我们通过创建一个以名为 Animal 的基类开始的类层次结构来建模动物的行为。动物能够做不同的事情,比如飞行、挖掘和行走,但也有一些常见的操作,比如吃饭、睡觉和发出声音。所有动物都会执行一些常见的操作,但方式也不同。当以不同方式执行操作时,它是抽象方法的良好候选者(强制子类提供自定义实现)。让我们看一个非常原始的 Animal 基类,它定义了一个用于发出声音(例如狗叫、牛叫或猪叫)的抽象方法。
\n\npublic abstract Animal {\n\npublic void sleep{\n// sleeping time\n}\npublic void eat(food)\n{\n//eat something\n}\npublic abstract void makeNoise();\n}\npublic Dog extends Animal {\n public void makeNoise() {\n System.out.println("Bark! Bark!");\n }\n}\npublic Cow extends Animal {\n public void makeNoise() {\n System.out.println("Moo! Moo!");\n }\n}\nRun Code Online (Sandbox Code Playgroud)\n\n请注意,abstract 关键字用于表示抽象方法和抽象类。现在,任何想要实例化的动物(如狗或牛)都必须实现 makeNoise 方法 - 否则无法创建该类的实例。让我们看一下扩展 Animal 类的 Dog 和 Cow 子类。
\n\n现在您可能想知道为什么不将抽象类声明为接口,并让 Dog 和 Cow 实现该接口。当然可以 - 但您还需要实现 eat 和 sleep 方法。通过使用抽象类,您可以继承其他(非抽象)方法的实现。您不能使用接口来做到这一点 - 接口不能提供任何方法实现。
\n\n简而言之,接口应该包含所有抽象方法,但不包含方法的实现,或者我们不能在接口中定义非抽象方法,在接口中所有方法都应该是抽象的,但在抽象类中我们可以同时定义抽象方法和非抽象方法。抽象方法,因此对于定义非抽象方法,我们不必定义另一个类来实现同一对象的行为,这是抽象类相对于接口的优势。
\n|   归档时间:  |  
           
  |  
        
|   查看次数:  |  
           24340 次  |  
        
|   最近记录:  |