从另一个抽象类继承来的抽象类的重要性是什么

时间:2019-03-29 06:07:40

标签: java abstract-class

大约两个月前,我才刚开始使用Java,而我正尝试着更多地理解抽象类。我了解抽象及其实现的基本概念,但是我不明白的是,为什么抽象类扩展了另一个抽象类以及它添加了哪些功能。另外,我看到了一个抽象类,该抽象类扩展了另一个抽象类,但是它仅实现另一个抽象类的一个功能。

我确实在查找示例代码,但是它们仅显示实现,而没有任何解释:

public abstract class Beverage {

   String description = "Beverage";

   public String getDescription(){
      return description;
   }
     public abstract double cost();

 }

// abstract class CondimentDecorator 
   public abstract class CondimentDecorator extends Beverage {

       @Override
       public abstract String getDescription();
 }

如您所见,抽象类CondimentDecorator并没有实现Beverage抽象类中的所有功能。它仅实现getDescription()函数。但是,如果CondimentDecorator是具体的,则将需要实现Beverage抽象类内部的所有功能。

3 个答案:

答案 0 :(得分:4)

当一个抽象类扩展另一个抽象类时,这完全没问题。这只是意味着它详细说明基于旧类的行为新类的行为。但是它仍然不是一个完整的对象,因为它的某些行为仍然未知。

类似于现实世界。
假设您有一个Vehicle班。它可以是任何车辆:汽车,飞机,公共汽车,自行车等。这是您的抽象类。现在可以使用吗?不,因为您不知道是必须踩踏板还是转动方向盘。
现在,您创建另一个类,例如Car extends Vehicle。现在可以使用吗?可能吧,但是您仍然不知道它是卡车还是客车。但是你知道它有方向盘。
最后,当您再创建一个类时,例如说MySuperPassengerCar extends Car,您确切地知道这是什么对象,如何使用它以及它具有什么方法。

答案 1 :(得分:2)

Abstract类定义抽象方法。任何扩展另一个类的类都可以通过添加更多行为来增强超类。如果子类是抽象的,则可以添加一些抽象的行为。

抽象方法就像合同。其他代码可以使用现有代码,并可以依赖它。具体类必须通过提供实现来遵守合同。

下面举个例子看看。

public abstract class SuperAbstract {
      public void nonAbstract(){
            // some code
      }
      public abstract void contract();
}

public abstract class SubAbstract extends SuperAbstract{
       public void additionalNonAbstract()
             // some code
        }
        public abstract void additionalContract();
 }

public class Concrete extends SubAbstract{
       public void contract(){
             // implementation
       }
       public void additionalContract(){
               //implementation
       }
}

// although below is allowed and sometimes when we use an external library then this is one of the way but still this is not a good practice. 
// dependencies should be on abstractions only and not on concrete implementation
public abstract class AnotherAbstract extends Concrete{
       public void someMethod(){
             //some code
       }
       public abstract void oneMoreContract();
}

public class ConcreteA extends AnotherAbstract{
        public void oneMoreContract(){
               //some implementation
        }
}

现在请注意,我们总共定义了3个合约,ConcreteA具有所有实现。还要注意,由于Concrete为方法contractadditionalContract提供了实现,因此这些实现被ConcreteA

继承。

消费者代码可以轻松地依赖抽象。让我们在用户代码(消费者代码)中查看

  public class Consumer{
      public void m1(SuperAbstract c)
             c.contract();
             c.nonAbstract();
     }
     public void m2(AnotherAbstract c){
          c.contract();
          c.nonAbstract();
          c.oneMoreContract();
          c.additionalContract();
    }
 }

现在让我们看一下提供依赖性的接线代码

 public class Main{
       public static void main(String[] args){
            Consumer c = new Consumer();
             c.m1(new Concrete());
             c.m1(new ConcreteA());
             c.m2(new ConcreteA());
     }
}

答案 2 :(得分:1)

抽象类不必执行任何操作。可以,但是没有这样的要求。唯一要做的就是在具体类中提供接口和抽象类的抽象方法的实现。在复杂的层次结构中,尽管可以在中间抽象类中实现某些抽象方法,但并非所有内容都必须在具体类中。