繁体   English   中英

从另一个抽象类扩展的抽象类的重要性是什么

[英]What is the importance of abstract class that extends from another 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抽象类中的所有功能。

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

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

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

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

让我们用下面的例子来看看它。

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM