摘要与常规超级班级

时间:2012-10-26 00:33:25

标签: oop

如果我可以用抽象类做的一切,我可以使用常规超类, 当我可以使用常规超类时,为什么我会使用抽象类?

3 个答案:

答案 0 :(得分:12)

我认为这些评论和答案已经暗示了这一点,但我想更坦率地说明:你不能用普通的超级类来完成所有事情,你可以用抽象类来做。抽象类允许您定义方法的签名而不包括其实现,并且抽象类将不允许您直接实例化它。

因此,如果我有3个方法的类签名,并且我不想共享其中任何一个的实现,我将使用一个接口。 如果我想分享其中一个方法的实现,我将使用一个抽象类,然后在该类抽象中创建两个方法。 如果我想要共享方法的所有实现,我将使用抽象类,如果它直接实例化它是没有意义的,或者如果它的话我将使用常规类。

(这是基于我在C#方面的经验。语言之间的细节不同。)

答案 1 :(得分:1)

基类提供自己的方法实现。有时可以覆盖这些实现(取决于语言)。

抽象类没有提供默认实现,每个继承类都需要根据具体情况实现这些方法。

上述细节因语言而异。阅读相应的文档。

请考虑以下示例:
Number抽象类具有add()方法。 OddNumberEvenNumber子类需要实现几乎相同的add()方法,因此存在一些代码重复。在这里,拥有一个超级类更有意义(或者,至少有一个RealNumber的{​​{1}}子类。

但是,如果Number的数字不是抽象的,则将Complex视为Number的子类,add()中找到Number方法(假设它是实数加法算法)复杂的数字是没有意义的。这里抽象类更有意义。有些语言允许你覆盖超类方法,但在这种情况下这有点尴尬。

答案 2 :(得分:1)

当您需要以通用方式表示许多类似事物时,抽象类非常有用。

例如,假设你想在代码中代表动物园,你需要获得购物清单以确保你有合适的食物。你如何代表所有动物最喜欢的食物?每个人产生什么噪音?他们如何移动怎么样?您可以尝试使用超类来保存食物,噪音和动作的大列表,但是对于动物有一个共同的定义更容易,然后让每只动物提供自己的实现细节:

   public class Zoo {
      public Animals[] AnimalsInZoo { get; set;}

      public List<Food> GetGroceryList(){
         List<Food> groceries = new List<Food>();
         foreach(Animal a in Animals[]){
            groceries.Add(a.FavoriteFood);
         }
         return groceries;
      }

      public void  MakeAnimalsSing(){

         foreach(Animal a in Animals[]){
            a.MakeNoise();
         }

      }
   }

抽象的Animal类看起来像:

   public abstract class Animal {
      public abstract void MakeNoise();
      public abstract Food FavoriteFood { get; }
      public abstract void Move();
   }

并说动物园有两种类型的动物:

   public class Panda : Animal{
      public override void MakeNoise(){
         // grunt
      }

      public override void Move(){
         // walk
      }

      public override Food FavoriteFood { 
         get {
              return new Bamboo();
         }
      }
   }  

      public class Parrot: Animal{
      public override void MakeNoise(){
         // talk
      }

      public override void Move(){
         // fly
      }

      public override Food FavoriteFood { 
         get {
              return new Cracker();
         }
      }
   }  

通过一个共同的抽象类,我可以轻松地使用任意数量的不同动物类型,而无需明确知道我正在使用哪一个,但每个都可以按照自己的方式行事。

超类只是无法提供这种灵活性或细节。