Oop 接口与抽象类(通用OO)

Oop 接口与抽象类(通用OO),oop,interface,abstract-class,Oop,Interface,Abstract Class,我最近接受了两次电话采访,有人问我接口和抽象类之间的区别。我已经解释了我能想到的每一个方面,但他们似乎在等我提到一些具体的东西,我不知道是什么 根据我的经验,我认为以下是正确的。如果我遗漏了一个要点,请告诉我 界面: 接口中声明的每个方法都必须在子类中实现。 接口中只能存在事件、委托、属性(C#)和方法。一个类可以实现多个接口 抽象类: 子类只能实现抽象方法。抽象类可以具有带有实现的普通方法。除了事件、委托、属性和方法之外,抽象类还可以有类变量。由于C#中不存在多重继承,一个类只能实现一个抽象类

我最近接受了两次电话采访,有人问我接口和抽象类之间的区别。我已经解释了我能想到的每一个方面,但他们似乎在等我提到一些具体的东西,我不知道是什么

根据我的经验,我认为以下是正确的。如果我遗漏了一个要点,请告诉我

界面:

接口中声明的每个方法都必须在子类中实现。 接口中只能存在事件、委托、属性(C#)和方法。一个类可以实现多个接口

抽象类:

子类只能实现抽象方法。抽象类可以具有带有实现的普通方法。除了事件、委托、属性和方法之外,抽象类还可以有类变量。由于C#中不存在多重继承,一个类只能实现一个抽象类

  • 在所有这些之后,面试官提出了一个问题“如果你有一个只包含抽象方法的抽象类怎么办?这与接口有什么不同?”我不知道答案,但我认为这是上面提到的继承,对吗

  • 另一位面试官问我,如果在接口中有一个公共变量,这与抽象类中有什么不同?我坚持在接口中不能有公共变量。我不知道他想听什么,但他也不满意

  • 另见


      • 还有一些其他的区别-

        接口不能有任何具体的实现。抽象基类可以。这允许您在那里提供具体的实现。这可以允许抽象基类实际提供更严格的契约,而接口实际上只描述类的使用方式。(抽象基类可以具有定义行为的非虚拟成员,这为基类作者提供了更多控制。)

        一个类上可以实现多个接口。类只能从单个抽象基类派生。这允许使用接口实现多态层次结构,但不允许使用抽象基类。这还允许使用接口进行伪多重继承

        可以在v2+中修改抽象基类,而无需破坏API。对接口的更改是破坏性的更改

        与抽象基类不同,[C#/.NET专用]接口可以应用于值类型(结构)。结构不能从抽象基类继承。这允许对价值类型应用行为契约/使用指南。

        对于.Net

        你对第二个面试官的回答也是对第一个面试官的回答。。。抽象类可以有实现,而状态、接口不能


        编辑:另一方面,我甚至不会使用短语“subclass”(或“继承”短语)来描述“定义为实现”接口的类。对我来说,接口是一个契约的定义,如果类被定义为“实现”该接口,那么它必须遵守该契约。它没有继承任何东西。。。您必须自己明确地添加所有内容

        面试官们正在一棵奇怪的树上吠叫。对于C语言和java语言,有不同之处,但是在C++语言中没有。OO理论并没有区分这两者,仅仅是语言的语法

        抽象类是一个同时具有实现和接口(纯虚拟方法)的类,将被继承。接口通常没有任何实现,只有纯虚拟函数

        在C#或Java中,没有任何实现的抽象类与接口的区别仅在于用于从接口继承的语法以及只能从其中一个继承的事实。

        从,主要涉及何时使用一个或另一个:

        根据我的经验,界面是最好的 当您有几个类时使用 每个人都需要对同样的问题做出反应 方法,以便可以 可与其他代码互换使用 这将被写在那些 类的公共接口。最好的 当 协议很重要,但是 潜在的逻辑可能不同于 每节课。如果你不是这样的话 复制逻辑,考虑抽象 类还是标准类继承 相反

        1) 一个接口可以看作是一个纯抽象类,是相同的,但尽管如此,实现一个接口和继承一个抽象类并不相同。当您从这个纯抽象类继承时,您正在定义一个层次结构->继承,如果您实现的接口不是您自己,那么您可以实现任意多的接口,但是您只能从一个类继承

        2) 可以在接口中定义属性,因此实现该接口的类必须具有该属性

        例如:

          public interface IVariable
          {
              string name {get; set;}
          }
        

        实现该接口的类必须具有这样的属性。

        通过实现接口,您实现的是组合(“has-a”关系),而不是继承(“is-a”关系)。这是一个重要的原则,当涉及到设计模式时,你需要使用接口来实现行为的组合而不是继承。

        当你的问题表明它是针对“通用OO”时,它似乎真的关注于.NET对这些术语的使用

        在.NET中(与Java类似):

        • 接口不能有状态或实现
        • 实现接口的类必须提供该接口所有方法的实现
        • 抽象类可能包含状态(数据成员)和/或实现(方法)
        • 抽象类可以在
          public class Vehicle {
              private Driver driver;
              private Seat[] seatArray; //In java and most of the Object Oriented Programming(OOP) languages, square brackets are used to denote arrays(Collections).
              //You can define as many properties as you want here ...
          }
          
          public class Bicycle extends Vehicle {
              //You define properties which are unique to bicycles here ...
              private Pedal pedal;
          }
          
          public class Car extends Vehicle {
              private Engine engine;
              private Door[] doors;
          }
          
          //......Code of Vehicle Class
          abstract public void drive();
          //.....Code continues
          
          public interface Dialable {
              public void dial(Number n);
          }
          
          // Makers define how exactly dialable work inside.
          
          Dialable PHONE1 = new Dialable() {
              public void dial(Number n) {
                  //Do the phone1's own way to dial a number
              }
          }
          
          Dialable PHONE2 = new Dialable() {
              public void dial(Number n) {
                  //Do the phone2's own way to dial a number
              }
          }
          
          
          //Suppose there is a function written by someone else, which expects a Dialable
          ......
          public static void main(String[] args) {
              Dialable myDialable = SomeLibrary.PHONE1;
              SomeOtherLibrary.doSomethingUsingADialable(myDialable);
          }
          .....
          
          ......
          public static void main(String[] args) {
              Dialable myDialable = SomeLibrary.PHONE2; // <-- changed from PHONE1 to PHONE2
              SomeOtherLibrary.doSomethingUsingADialable(myDialable);
          }
          .....
          
          After all that, the interviewer came up with the question "What if you had an 
          Abstract class with only abstract methods? How would that be different
          from an interface?" 
          
          An another interviewer asked me what if you had a Public variable inside
          the interface, how would that be different than in Abstract Class?
          
          public abstract class CloneableType
          {
          // Only derived types can support this
          // "polymorphic interface." Classes in other
          // hierarchies have no access to this abstract
          // member.
             public abstract object Clone();
          }
          
          // Nope! Multiple inheritance is not possible in C#
          // for classes.
          public class MiniVan : Car, CloneableType
          {
          }
          
          public interface ICloneable
          {
          object Clone();
          }
          
          public class Cars
          {
              public string DigitalFuelMeter()
              {
                  return "I have DigitalFuelMeter";
              }
          
              public string AirCondition()
              {
                  return "I have AC";
              }
          
              public string SeatAdjust()
              {
                  return "I can Adjust seat";
              }
          }
          
          public class Alto : Cars
          {
              // Have all the features of Car class    
          }
          
          public class Verna : Cars
          {
              // Have all the features of Car class + Car need to inherit ABS as the Braking technology feature which is not in Cars        
          }
          
          public class Cruze : Cars
          {
              // Have all the features of Car class + Car need to inherit EBD as the Braking technology feature which is not in Cars        
          }
          
          public abstract class Brake
          {
              public abstract string GetBrakeTechnology();
          }
          
          public class Verna : Cars,Brake
          {
              public override string GetBrakeTechnology()
              {
                  return "I use ABS system for braking";
              }       
          }
          
          public class Cruze : Cars,Brake
          {
              public override string GetBrakeTechnology()
              {
                 return "I use EBD system for braking";
              }         
          }
          
          interface IBrakeTechnology
          {
              string GetBrakeTechnology();
          }
          
          public class Verna : Cars, IBrakeTechnology
          {
              public string GetBrakeTechnology()
              {
                  return "I use ABS system for braking";
              }
          }
          
          public class Cruze : Cars, IBrakeTechnology
          {
             public string GetBrakeTechnology()
             {
                 return "I use EBD system for braking";
             }        
          }
          
          abstract class Car
          {
             string color;
             int speed;
          }
          class HondaAccord : Car
          {
             MusicPlayer musicPlayer;
          }
          
          abstract class Car
          {
              string color;
              int speed;
          }
          class HondaAccord : Car, IInflateAir, IRefueling
          {
              MusicPlayer musicPlayer;
          }