我在问一个非常基本的问题,它可能被标记为重复(虽然我找不到答案):
是否有任何抽象类的实际示例,其中所有方法都声明为抽象?
在大多数情况下,正如 Java 教程中所提到的,具有所有抽象方法的类应该是一个接口。
但是由于抽象类和接口是两个不同的概念,我正在寻找一个具有“完整抽象类”的例子
我在问一个非常基本的问题,它可能被标记为重复(虽然我找不到答案):
是否有任何抽象类的实际示例,其中所有方法都声明为抽象?
在大多数情况下,正如 Java 教程中所提到的,具有所有抽象方法的类应该是一个接口。
但是由于抽象类和接口是两个不同的概念,我正在寻找一个具有“完整抽象类”的例子
我认为唯一实用的方法是Abstract class
可以保持状态。因此,您可以拥有具有访问级别的内部属性protected
,并且您可以protected abstract methods
在界面中创建它,您不能导致所有都是public
。
一个实际的例子可能是这样,java中的受保护方法具有“继承访问”和“包访问”。
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();
}
使用抽象类的缺点是你也失去了扩展其他东西的可能性。
除了保持状态,值得记住的是所有接口成员都是隐式的public
。因此,限制抽象方法的可见性本身可能是使用抽象类而不是接口的一个足够令人信服的理由。
除了上面给出的两个答案之外,接口只能有常量(变量是公共的、静态的和最终的),而抽象类没有这样的限制。
抽象类可以具有构造函数,当子类被实例化时(如果它是非参数化的),这些构造函数将被隐式调用。但这对于接口是不可能的。
这是一个使用抽象类的例子
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
}
}
}
抽象类的另一个通用目的是防止类的实例。例如
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 的对象。
一个接口可以应用于非常不同的类。彼此没有关系的类是Serializable
或Cloneable
。但是,抽象类的子类都是相关的。这在实现接口或扩展抽象类时可能没有任何意义,但它在语义上意味着一些东西。
有一种编程风格,其中基类的所有方法都是public final
,protected abstract
和protected
空的,或者private
。但即使这也不是 OP 感兴趣的。
我能想到的最简单的实际示例是具有受保护变量的类:
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...
}
你不能用接口来做到这一点。
在以下答案中添加更多内容:
接口为您提供了一个合同来实现抽象类也可以为您提供一个模板。对于一个简单的场景,您可以使用接口或抽象类而无需考虑太多。但是拥有一个仅用于维护状态的抽象类可能会给您在复杂的实现中带来很多问题。在这种情况下,您必须仔细考虑您真正想要在代码中实现的目标并做出决定。如果您考虑在代码中维护状态的情况,您始终可以在实现中使用状态模式,因此您将能够在代码中使用接口。在决定使用抽象类而不是接口之前,您应该始终考虑代码的可扩展性和可维护性。
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");
}
}
拥有纯抽象类的最大动机是允许未来的扩展。假设您有一个抽象类(具有所有抽象成员),然后您在 20 个派生类中继承该抽象类。将来某个时候,您希望为您的 5 个派生类添加一个公共方法,您会怎么做?
由于您已经继承了抽象类,因此更简单的解决方案是将方法(带有实现)添加到抽象类。这样您就不必接触任何派生类。在这种情况下,接口非常严格,一旦创建,就几乎没有机会更改接口,因为它需要更改实现该接口的所有类。