最近我读到一个抽象方法本质上创建了一个标记为继承的方法,它是无块的,等待子类特化。那么我问这个:创建一个抽象方法,允许它的继承,并制作一个子类版本,没有对应的超类方法,只有一个由/在子类中定义有什么区别。根据覆盖原则,子类对象不应该自动使用子类方法,如果没有对应的超类方法,子类对象将始终使用子类方法。创建一个抽象方法的目的是什么,而不仅仅是一个没有超类对应物的标准方法。
我的知识可能完全有缺陷并扭曲了我的看法:-) 任何和所有的帮助都将不胜感激
最近我读到一个抽象方法本质上创建了一个标记为继承的方法,它是无块的,等待子类特化。那么我问这个:创建一个抽象方法,允许它的继承,并制作一个子类版本,没有对应的超类方法,只有一个由/在子类中定义有什么区别。根据覆盖原则,子类对象不应该自动使用子类方法,如果没有对应的超类方法,子类对象将始终使用子类方法。创建一个抽象方法的目的是什么,而不仅仅是一个没有超类对应物的标准方法。
我的知识可能完全有缺陷并扭曲了我的看法:-) 任何和所有的帮助都将不胜感激
它与多态性有关;一个班级表现得像另一个班级的能力。
以有一个名为的抽象类为例,Animal
它是 and 的子Dog
类Fish
。如果在Animal
类中我们有一个抽象方法move()
,那么两者都Dog
将Fish
被迫实现该move()
方法。
public class Animal {
public abstract void move();
}
public class Dog extends Animal {
public void move() {
System.out.println("walk");
}
}
public class Fish extends Animal {
public void move() {
System.out.println("swim");
}
}
此外,如果我们在某处有一个辅助方法:
public static void moveTheAnimal(Animal a) {
a.move();
}
然后我们知道,无论提供什么具体的类(子类),都保证定义了一个move()
方法。
另一方面,如果类中没有抽象方法move()
,Animal
我们将需要一个moveTheDog(Dog d)
等 moveTheFish(Fish f)
来为每个可能的动物。
超类可以通过抽象方法将其部分职责委托给子类。这样做的好处是超类将只包含通用的可重用逻辑,更具体的实现细节将被向下推到继承树的子类中。
在这种情况下,超类仍然可能需要访问某些方法,就好像它们已经实现一样。这就是为什么你需要在超类中定义抽象的无主体方法——否则它将无法引用它们!
例如,超类可以处理数据,而具体的子类可以处理来自各种来源的数据输入。在这种情况下,超类和子类可能如下所示:
class DataProcessor {
public void doWork() {
Data data = readData();
processData(data);
}
public abstract Data readData(); // this method is here and marked as abstract to make sure that:
// 1. child classes never fail to implement it;
// 2. parent class have a possibility to refer to the method that he is not actually implementing;
// 3. users of parent class have a possibility to refer to the method that parent is not capable of implementing.
}
class FileSystemDataProcessor extends DataProcessor {
public Data readData();
// handle data reading from the file system
}
}
抽象方法的目的是告诉开发人员您希望每个子类都有该方法的实现。下面是一个示例:
public class Animal {
public abstract void move(); // you expect that every animal will be able to move
}
public class Bird extends Animal {
@Override
public void move() { ... }
public void fly() { ... } // Birds can fly
}
public class Dog extends Animal {
@Override
public void move() { ... }
}
public class Pig extends Animal {
public void oink();
} // COMPILE ERROR
然后,当您有一个接受Animal
对象的函数时,您还暗示该函数不会执行任何Bird
、Dog
或Pig
特定的操作。
如果您在Animal
超类中未提供抽象方法声明,则此类函数将无法编译,因为它无法保证其任何子类都有move()
方法。