Java 抽象类和所有方法抽象-实用示例

Java 抽象类和所有方法抽象-实用示例,java,inheritance,interface,abstract,Java,Inheritance,Interface,Abstract,我问了一个非常基本的问题,它可能被标记为重复(但我找不到答案): 有没有一个抽象类具有所有 声明为抽象的方法 在大多数情况下,正如Java教程中提到的,带有所有方法抽象的类应该是一个接口 但是,由于抽象类和接口是两个不同的概念,我正在寻找一个例子来说明“完整的抽象类”我认为唯一实用的方法是抽象类可以保持状态。因此,您可以拥有访问级别为受保护的内部属性,并且您可以创建受保护的抽象方法,这样在接口中就不能使所有的都是公共的 例如,java中的受保护方法具有“继承访问权”和“包访问权” public

我问了一个非常基本的问题,它可能被标记为重复(但我找不到答案):

有没有一个抽象类具有所有 声明为抽象的方法

在大多数情况下,正如Java教程中提到的,带有所有方法抽象的类应该是一个接口


但是,由于抽象类和接口是两个不同的概念,我正在寻找一个例子来说明“完整的抽象类”

我认为唯一实用的方法是
抽象类可以保持状态。因此,您可以拥有访问级别为
受保护的
内部属性,并且您可以创建
受保护的抽象方法
,这样在接口中就不能使所有的
都是公共的

例如,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 abstract void speak(){
        System.out.println("animal voice");
    }
}

public class dog extends animal{
    public void speak(){
        System.out.println("dog voice");
    }
}
  • 除了上面给出的两个答案之外,接口只能有常量(公共、静态和最终变量),而抽象类没有此类限制

  • 抽象类可以有构造函数,当子类被实例化时(如果它是非参数化的),构造函数将被隐式调用。但这在接口中是不可能的

  • 下面是一个使用抽象类的示例

    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);
     }
     }
    

    在上面的代码中,我有效地确保了不会有实例哺乳动物的对象。

    接口可以应用于完全不同的类。相互之间没有关系的类是
    可序列化的
    可克隆的
    。然而,抽象类的子类都是相关的。在实现接口或扩展抽象类时,这可能并不意味着什么,但在语义上意味着什么


    有一种编程风格,其中基类的所有方法要么是
    public final
    protected abstract
    protected
    和empty,要么是
    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");
        }
    }
    

    接口为您提供了一个契约来实现,其中抽象类也可以为您提供一个模板。对于一个简单的场景,您可以使用接口或抽象类,而无需考虑太多。但是,在一个复杂的实现中,拥有一个仅用于维护状态的抽象类可能会给您带来很多问题。在这种情况下,你必须仔细考虑你真正想要在代码中实现什么并做出决定。如果考虑在代码中维护状态的情况,则可以始终在实现中使用该状态,这样您就可以在代码中使用接口。在决定在接口上使用抽象类之前,应该始终考虑代码的扩展能力和可维护性。

    < P> > <强>纯抽象类< /强>的最大动机是允许将来的扩展。假设您有一个抽象类(包含所有抽象成员),那么您将在20个派生类中继承该抽象类。在将来的某个时候,您希望向5个派生类添加一个公共方法,您会怎么做

    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");
        }
    }
    


    由于您已经继承了抽象类,因此更简单的解决方案是将方法(带实现)添加到抽象类中。这样,您就不必接触任何派生类。在这种情况下,接口是非常严格的,一旦创建,就几乎没有机会更改接口,因为它需要更改实现该接口的所有类。

    区别在于
    限制可见性
    。这很好,它并没有回答为什么一个具有所有方法的类都是抽象的。抽象类不支持多重继承,例如在上面的代码中,如果你想阻止人类从哺乳动物和爬行动物中扩展出来,你可以通过确保哺乳动物是抽象类来有效地阻止它。NumberOfThries没有意义inaccesible@nachokk-哎呀。。。这就是我的意思。愚蠢的错误:-0不确定此示例与问题的相关性如何