我问的是一个非常基本的问题,它可能会被标记为重复(但我找不到答案):
是否有任何抽象类的实际例子 声明为Abstract的方法?
在大多数情况下,如同Java教程中所提到的那样,所有方法抽象的类都应该是一个接口。
但是,由于抽象类和接口是两个不同的概念,我正在寻找一个令人信服的例子,有“完整的抽象类”
答案 0 :(得分:5)
我认为唯一可行的方法是Abstract class
可以保持状态。因此,您可以拥有访问级别为protected
的内部属性,并且您可以在界面中protected abstract methods
使public
成为public interface Operation{
void operate();
}
public abstract class AbstractClase implements Operation{
protected Operation delegate;
public AbstractClase(Operation delegate){
this.delegate=delegate;
}
//delegate implementation responsability to children
protected abstract doSomething();
}
。
一个实际的例子就是这样,java中的protected方法有'继承访问'和'包访问'。
{{1}}
使用抽象类的缺点是你也失去了扩展其他东西的可能性。
答案 1 :(得分:4)
除了保持状态之外,还值得记住所有接口成员都是隐式public
。因此,限制抽象方法的可见性本身可能是使用抽象类而不是接口的充分理由。
答案 2 :(得分:3)
添加上面给出的两个答案,接口只能有常量(变量是public,static和final),而对抽象类没有这样的限制。
抽象类可以具有构造函数,这些构造函数将在实例化子类时(如果它是非参数化的)隐式调用。但这对接口来说是不可能的。
以下是使用抽象类
的示例abstract class Animal{
public int noOfLegs;
public boolean isAlive;
Animal(){
isAlive = true;
}
public abstract void walk();
}
class Cow extends Animal{
Cow(){
noOfLegs = 4;
}
public void walk(){
if(isAlive){
//Code for walking
}
}
}
答案 3 :(得分:0)
抽象类的另一个通用目的是阻止类的实例。例如
abstract class Mammal{
int i=0;
}
public class Man extends Mammal{
public setMeValue(int i){
this.i=i;
}
public static void main(String args[]){
Mammal m= new Man();
man.setMeValue(10);
}
}
在上面的代码中,我有效地确保永远不会有实例Mammal的对象。
答案 4 :(得分:0)
接口可以应用于完全不同的类。彼此无关的类是Serializable
或Cloneable
。但是,抽象类的子类都是相关的。在实现接口或扩展抽象类时,这可能没有任何意义,但它在语义上意味着什么。
有一种编程风格,其中基类的所有方法都是public final
,protected abstract
,protected
和空,或private
。但即使这不是OP感兴趣的内容。
答案 5 :(得分:0)
我能想到的最简单的实际例子是一个具有受保护变量的类:
public abstract class RoadVehicle {
protected int numberOfTires;
protected String vinNumber;
protected VehicleRegistration registration;
public abstract void drive();
public abstract double calculateToll();
public abstract void changeTires();
// so on and so forth...
}
您无法通过界面执行此操作。
答案 6 :(得分:0)
在以下答案中添加更多内容:
接口为您提供了一个实现合同的合同,抽象类也可以为您提供模板。对于一个简单的场景,您可以使用接口或抽象类而不必考虑太多。但是,为了维护状态而拥有一个抽象类可能会在复杂的实现中给你带来很多问题。在这种情况下,您必须仔细考虑您希望在代码中实现的目标并做出决定。如果您考虑在代码中维护状态的情况,您可以始终在实现中使用State pattern,这样您就可以在代码中使用接口。在决定在接口上使用抽象类之前,应始终考虑代码的扩展能力和可维护性。
答案 7 :(得分:0)
public abstract class animal{
public abstract void speak(){
System.out.println("animal voice");
}
}
public class dog extends animal{
public void speak(){
System.out.println("dog voice");
}
}
答案 8 :(得分:0)
纯抽象类背后的最大动机是允许未来的扩展。假设您有一个Abstract类(包含所有抽象成员),那么您将在20个派生类中继承该抽象类。将来某个时候你希望为你的5个派生类添加一个公共方法,你会怎么做?
由于您已经继承了抽象类,因此更简单的解决方案是将方法(带有实现)添加到抽象类中。这样您就不必触及任何派生类。接口在这种情况下是非常严格的,一旦创建,就很少有机会更改接口,因为它需要更改实现该接口的所有类。