首页 文章

接口和抽象类之间有什么区别?

提问于
浏览
1561

接口和抽象类之间究竟有什么区别?

30 回答

  • 3

    这是一个非常对接口与抽象类的基本理解 .

  • 35

    唯一的区别是,一个人可以参与多重继承,而其他人则不能 .

    接口的定义随着时间的推移而发生了变化 . 你认为一个接口只有方法声明而且只是 Contract 吗?那么静态最终变量以及Java 8之后的默认定义呢?

    接口被引入Java,因为the diamond problem具有多重继承,这就是他们实际打算做的事情 .

    接口是为了避免多重继承问题而创建的构造,可以包含抽象方法,默认定义和静态最终变量 .

    Why does Java allow static final variables in interfaces when they are only intended to be contracts? .

  • 4

    我想补充一点其他有意义的差异 . 例如,您有一个包含数千行代码的框架 . 现在,如果您想使用方法enhanceUI()在整个代码中添加新功能,那么最好在抽象类中添加该方法,而不是在接口中添加 . 因为,如果在接口中添加此方法,则应在所有实现的类中实现它,但如果在抽象类中添加该方法则不是这种情况 .

  • 1

    不是原始问题的答案,但是一旦你得到它们之间的差异的答案,你将进入使用时 - 每个困境:When to use interfaces or abstract classes? When to use both?

    我对OOP的知识有限,但是看到界面作为语法形容词的等价物直到现在都适用于我(如果这种方法是假的,请纠正我!) . 例如,接口名称就像您可以为类提供的属性或功能,并且类可以包含许多类:ISerializable,ICountable,IList,ICacheable,IHappy,...

  • 8

    一些重要的差异:

    以表格的形式:

    Difference

    stated by Joe from javapapers

    1.主要区别是Java接口的方法是隐式抽象的,不能有实现 . Java抽象类可以具有实现默认行为的实例方法 . 2.在Java接口中声明的变量默认为final . 抽象类可能包含非最终变量 . 3.默认情况下,Java接口的成员是公共的 . Java抽象类可以具有通常的类成员,如private,protected等.4.Java接口应该使用关键字“implements”实现;应使用关键字“extends”扩展Java抽象类 . 5.接口只能扩展另一个Java接口,抽象类可以扩展另一个Java类并实现多个Java接口 . 6. Java类可以实现多个接口,但它只能扩展一个抽象类 . 7.Interface是绝对抽象的,无法实例化; Java抽象类也无法实例化,但如果存在main(),则可以调用它 . 8.与java抽象类相比,java接口很慢,因为它需要额外的间接 .

  • 12

    Differences between abstract class and interface on behalf of real implementation.

    Interface :它是一个关键字,用于定义对象的模板或蓝图,它强制所有子类都遵循相同的原型,对于实现,所有子类都可以自由地实现功能 . 这是要求 .

    我们应该使用接口的一些其他用例 .

    两个外部对象之间的通信(我们的应用程序中的第三方集成)通过 Interface 这里完成接口作为 Contract .

    Abstract Class: Abstract,它是一个关键字,当我们在任何类之前使用这个关键字时它就变成了抽象类 . 它主要用于我们需要定义模板以及一个对象的一些默认功能,后面跟着所有子类并且这种方式它删除了冗余代码和 one more use cases where we can use abstract class ,比如我们希望没有其他类可以直接实例化该类的对象,只有派生类才能使用该功能 .

    Example of Abstract Class:

    public abstract class DesireCar
      {
    
     //It is an abstract method that defines the prototype.
         public abstract void Color();
    
      // It is a default implementation of a Wheel method as all the desire cars have the same no. of wheels.   
     // and hence no need to define this in all the sub classes in this way it saves the code duplicasy     
    
      public void Wheel() {          
    
                   Console.WriteLine("Car has four wheel");
                    }
               }
    
    
        **Here is the sub classes:**
    
         public class DesireCar1 : DesireCar
            {
                public override void Color()
                {
                    Console.WriteLine("This is a red color Desire car");
                }
            }
    
            public class DesireCar2 : DesireCar
            {
                public override void Color()
                {
                    Console.WriteLine("This is a red white Desire car");
                }
            }
    

    Example Of Interface:

    public interface IShape
            {
              // Defines the prototype(template) 
                void Draw();
            }
    
    
      // All the sub classes follow the same template but implementation can be different.
    
        public class Circle : IShape
        {
            public void Draw()
            {
                Console.WriteLine("This is a Circle");
            }
        }
    
        public class Rectangle : IShape
        {
            public void Draw()
            {
                Console.WriteLine("This is a Rectangle");
            }
        }
    
  • 2047

    可在此处找到解释:http://www.developer.com/lang/php/article.php/3604111/PHP-5-OOP-Interfaces-Abstract-Classes-and-the-Adapter-Pattern.htm

    抽象类是一个只由程序员部分实现的类 . 它可能包含一个或多个抽象方法 . 抽象方法只是一个函数定义,用于告诉程序员该方法必须在子类中实现 . 接口类似于抽象类;实际上,接口占用与类和抽象类相同的名称空间 . 因此,您无法定义与类同名的接口 . 接口是一个完全抽象的类;没有任何方法被实现,而是从它的类子类,它被称为实现该接口 .

    无论如何,我发现接口的这种解释有点令人困惑 . 更常见的定义是:接口定义实现类必须满足的 Contract . 接口定义由公共成员的签名组成,没有任何实现代码 .

  • 10

    你可以找到 interfaceabstract class. 之间的明显区别

    Interface

    • 界面只包含抽象方法 .

    • 强制用户在实现接口时实现所有方法 .

    • 仅包含final和static变量 .

    • 使用interface关键字声明 .

    • 接口的所有方法都必须定义为public .

    • 接口可以扩展,或者类可以实现多个其他接口 .

    Abstract class

    • Abstract类包含抽象和非抽象方法 .

    • 在继承抽象类时不强制用户实现所有方法 .

    • 包含各种变量,包括原始变量和非原始变量

    • 使用abstract关键字声明 .

    • 可以使用任何可见性定义抽象类的方法和成员 .

    • 子类只能扩展单个类(抽象或具体) .

  • 37

    继承用于两个目的:

    • 允许对象将父类型数据成员和方法实现视为自己的 .

    • 允许对需要引用超类型对象的代码使用一种类型的对象的引用 .

    在支持广义多重继承的语言/框架中,通常很少需要将类型分类为“接口”或“抽象类” . 然而,流行的语言和框架将允许类型将其他类型的数据成员或方法实现视为其自身,即使它们允许类型可替代任意数量的其他类型 .

    抽象类可能具有数据成员和方法实现,但只能由不从任何其他类继承的类继承 . 接口对实现它们的类型几乎没有限制,但不能包含任何数据成员或方法实现 .

    有时,类型可以替代许多不同的东西;还有一些时候,对象将父类型数据成员和方法实现视为自己的有用 . 区分接口和抽象类允许在最相关的情况下使用这些能力 .

  • 122

    接口仅包含功能的定义/签名,如果我们有一些共同的功能以及常见的签名,那么我们需要使用抽象类 . 通过使用抽象类,我们可以同时提供行为和功能 . 继承抽象类的另一个开发人员可以轻松使用此功能,因为他们只需填写空白 .

    取自:

    http://www.dotnetbull.com/2011/11/difference-between-abstract-class-and.html

    http://www.dotnetbull.com/2011/11/what-is-abstract-class-in-c-net.html http://www.dotnetbull.com/2011/11/what-is-interface-in-c-net.html

  • 9

    根据定义,接口不能具有任何方法的实现,并且无法初始化成员变量 .

    但是,抽象类可以实现方法并初始化成员变量 .

    当您期望 Contract 发生变化时,请使用抽象类,即,将来您可能需要添加新方法 .

    在这种情况下,如果您决定使用接口,当接口更改为包含接口时,您的应用程序将在您转储新接口DLL时中断 .

    要详细阅读,请访问difference between abstract class and a interface

  • 3

    抽象类是无法创建其对象的类或无法实例化的类 . 抽象方法使类抽象 . 需要继承抽象类以覆盖抽象类中声明的方法 . 访问说明符没有限制 . 抽象类可以有构造函数和其他具体(非abstarct方法)方法,但接口不能有 .

    界面是方法的蓝图/模板 . (例如,纸上的房子被给出(界面房子),不同的建筑师将使用他们的想法来构建它(实现房屋界面的建筑师类) . 它是一个集合抽象方法,默认方法,静态方法,最终变量和嵌套类 . 所有成员都是final或public,不允许使用protected和private访问说明符 . 不允许创建对象 . 必须创建一个类才能使用实现接口并覆盖接口中声明的抽象方法 . 接口是松散耦合的一个很好的例子(动态多态/动态绑定)接口实现多态和抽象 . 它告诉你做什么,但是如何做是由对于Eg . 有一家汽车公司,并且它想要制造所有汽车的某些功能是相同的,因此该公司将制造一种接口车辆,这将具有那些功能和不同类别的汽车(如Maruti Suzkhi,Maruti 800)将覆盖这些功能(功能) .

    为什么我们已经有抽象类的接口? Java仅支持多级和层级继承,但在接口的帮助下,我们可以实现多重继承 .

  • 3

    接口与抽象类的比较是错误的 . 应该有另外两个比较:1) interface vs. class 和2) abstract vs. final class .

    接口与类

    Interface 是两个对象之间的 Contract . 例如,我'm a Postman and you'是一个提供的包 . 我希望你知道你的送货地址 . 当有人给我一个包裹时,它必须知道它的送货地址:

    interface Package {
      String address();
    }
    

    Class 是一组遵守 Contract 的对象 . 例如,我是"Box"组的一个盒子,我遵守邮递员要求的 Contract . 同时我遵守其他 Contract :

    class Box implements Package, Property {
      @Override
      String address() {
        return "5th Street, New York, NY";
      }
      @Override
      Human owner() {
        // this method is part of another contract
      }
    }
    

    摘要与决赛

    Abstract class 是一组不完整的对象 . 他们可以__一个抽象的GPS感知框 - 我知道如何检查我在 Map 上的位置:

    abstract class GpsBox implements Package {
      @Override
      public abstract String address();
      protected Coordinates whereAmI() {
        // connect to GPS and return my current position
      }
    }
    

    如果由另一个类继承/扩展,该类可能非常有用 . 但它本身 - 它没用,因为它不能有物体 . 抽象类可以构建最终类的元素 .

    Final class 是一组完整的对象,可以使用,但是_117496_是一个总是到达构造期间指定的地址的Box:

    final class DirectBox implements Package {
      private final String to;
      public DirectBox(String addr) {
        this.to = addr;
      }
      @Override
      public String address() {
        return this.to;
      }
    }
    

    在大多数语言中,如Java或C,可能有 just a class ,既不是抽象的也不是最终的 . 这样的类可以继承并可以实例化 . 但我并不认为这严格符合面向对象的范式 .

    同样,将接口与抽象类进行比较是不正确的 .

  • 2

    接口

    接口是 contract :编写界面的人说:“嘿,我接受看起来那样的东西", and the person using the interface says "好吧,我写的课看起来那样” .

    An interface is an empty shell . 只有方法的签名,这意味着方法没有正文 . 界面可以只是一个模式 .

    例如(伪代码):

    // I say all motor vehicles should look like this:
    interface MotorVehicle
    {
        void run();
    
        int getFuel();
    }
    
    // My team mate complies and writes vehicle looking that way
    class Car implements MotorVehicle
    {
    
        int fuel;
    
        void run()
        {
            print("Wrroooooooom");
        }
    
    
        int getFuel()
        {
            return this.fuel;
        }
    }
    

    实现一个接口消耗很少的CPU,因为它不是一个类,只是一堆名称,因此没有任何昂贵的查找 . 它很重要,例如在嵌入式设备中 .


    抽象类

    与接口不同,抽象类是类 . 它们的使用成本更高,因为当你继承它们时会有一个查找 .

    抽象类看起来很像接口,但它们还有更多东西:您可以为它们定义行为 . 更多的是关于一个人说,“这些课程看起来应该是这样的,他们有共同点,所以填补空白!” .

    例如:

    // I say all motor vehicles should look like this:
    abstract class MotorVehicle
    {
    
        int fuel;
    
        // They ALL have fuel, so lets implement this for everybody.
        int getFuel()
        {
             return this.fuel;
        }
    
        // That can be very different, force them to provide their
        // own implementation.
        abstract void run();
    }
    
    // My teammate complies and writes vehicle looking that way
    class Car extends MotorVehicle
    {
        void run()
        {
            print("Wrroooooooom");
        }
    }
    

    实施

    虽然抽象类和接口应该是不同的概念,但实现使得该语句有时不真实 . 有时,它们甚至不是你认为的那样 .

    在Java中,强制执行此规则,而在PHP中,接口是没有声明方法的抽象类 .

    在Python中,抽象类更像是一个可以从ABC模块获得的编程技巧,实际上是使用元类,因此也就是类 . 接口与这种语言中的duck typing更相关,它是约定和调用描述符的特殊方法(__method__方法)之间的混合 .

    与编程一样,有另一种语言的理论,实践和实践:-)

  • 7

    abstract classinterface之间的关键技术差异是:

    • 抽象类可以有常量,成员,方法存根(没有主体的方法)和已定义的方法,而接口只能有常量和方法存根 .

    • 可以使用任何可见性定义抽象类的方法和成员,而接口的所有方法必须定义为 public (默认情况下它们是公共定义的) .

    • 在继承抽象类时,具体子类必须定义抽象方法,而抽象类可以扩展另一个抽象类,而不必定义父类中的抽象方法 .

    • 类似地,扩展另一个接口的接口不负责从父接口实现方法 . 这是因为接口无法定义任何实现 .

    • 子类只能扩展单个类(抽象或具体),而接口可以扩展,或者类可以实现多个其他接口 .

    • 子类可以定义具有相同或更少限制的可见性的抽象方法,而实现接口的类必须使用完全相同的可见性(公共)定义方法 .

  • 77

    让我们再次讨论这个问题:

    让你知道的第一件事是1/1和1 * 1会产生相同的结果,但这并不意味着乘法和除法是相同的 . 显然,他们保持着良好的关系,但请注意,两者都是不同的 .

    我将指出主要的不同之处,其余的已经解释过了:

    抽象类对于类层次结构的建模很有用 . 乍一看任何要求,我们都部分清楚 exactly 将被构建,但我们知道 what to build. 所以你的抽象类是你的基类 .

    接口对于让其他层次结构或类知道我能够做什么很有用 . 当你说我有能力时,你必须具备这种能力 . 接口将标记为类必须实现相同的功能 .

  • 2

    界面:转动(向左转,向右转 . )

    抽象类:轮子 .

    类别:方向盘,源自轮子,暴露界面转向

    一个用于对可以在各种事物中提供的行为进行分类,另一个用于对事物的本体建模 .

  • 3

    简而言之,差异如下:

    InterfaceAbstract Class 之间的语法差异:

    • 抽象类的方法和成员可以具有任何可见性 . interface 的所有方法必须是 public . //不再适用于Java 9

    • Abstract 类的具体子类必须定义所有抽象方法 . Abstract 子类可以有抽象方法 . 扩展另一个接口的接口不需要为从父接口继承的方法提供默认实现 .

    • 子类只能扩展一个类 . interface 可以扩展多个接口 . 一个类可以实现多个接口 .

    • 子类可以定义具有相同或更少限制的可见性的抽象方法,而实现 interface 的类必须将所有接口方法定义为public .

    • Abstract Classes 可以有构造函数但不能 interfaces .

    • Java 9中的接口具有私有静态方法 .

    现在在Interfaces中:

    public static - 支持
    public abstract - 支持
    public default - 支持
    private static - 支持
    private abstract - 编译错误
    private default - 编译错误
    private - 支持

  • 3

    最简单的总结是 interface 是:

    • 完全抽象,除了 defaultstatic 方法;虽然它有 defaultstatic 方法的定义(方法签名实现),但它只有其他方法的声明(方法签名) .

    • 遵守比规则更宽松的规则(一个类可以实现多个 interfaceinterface 可以从多个 interface 继承) . 所有变量都是隐式常量,无论是否指定为 public static final . 无论是否指定,所有成员都隐式 public .

    • 通常用于保证实现类具有指定的功能和/或与实现相同接口的任何其他类兼容 .

    同时, abstract 课程是:

    • 从完全抽象到完全实现的任何地方,倾向于拥有一个或多个 abstract 方法 . 可以包含声明和定义,声明标记为 abstract .

    • 一个完整的类,并且受制于管理其他类的规则(只能从一个类继承),条件是它无法实例化(因为完全实现了's no guarantee that it') . 可以有非常量成员变量 . 可以实现成员访问控制,将成员限制为 protectedprivate 或私有包(未指定) .

    • 通常用于提供可由多个子类共享的尽可能多的实现,或者提供程序员能够提供的尽可能多的实现 .

    或者,如果我们想将它全部归结为一个句子: interface 是实现类所具有的,但 abstract 类是子类的内容 .

  • 1

    许多初级开发人员错误地将接口,抽象和具体类视为同一事物的微小变化,并且纯粹基于技术理由选择其中一个:我是否需要多重继承?我需要一些地方来放置常用方法吗?我是否需要打扰除了具体课程之外的其他东西?这是错误的,隐藏在这些问题中的主要问题是: "I" . 当您自己编写代码时,您很少会想到其他现有或未来的开发人员在使用代码或使用代码 .

    接口和抽象类虽然从技术角度来看显然相似,但它们的含义和目的完全不同 .

    摘要

    • 一些实现将为您实现的接口 defines a contract .

    • 您的实现可以重用的抽象类 provides a default behavior .

    备选摘要

    • 接口用于定义公共API

    • 抽象类供内部使用,用于定义SPI

    关于隐藏实现细节的重要性

    具体的课程以非常具体的方式完成实际工作 . 例如, ArrayList 使用连续的内存区域以紧凑的方式存储对象列表,该方式提供快速随机访问,迭代和就地更改,但在插入,删除和偶尔添加时非常糟糕;同时, LinkedList 使用双链节点来存储对象列表,而是提供快速迭代,就地更改和插入/删除/添加,但随机访问非常糟糕 . 这两种类型的列表针对不同的用例进行了优化,重要的是你如何重视试图从你实例化的列表中挤出性能 .

    另一方面,列表的高级用户认为Java没有暴露 List 接口,但只有一个具体的 List 类实际上是 LinkedList 现在是什么 . 所有Java开发人员都会定制他们的代码以适应实现细节:避免随机访问,添加缓存以加快访问速度,或者只是自己重新实现 ArrayList ,尽管它与所有其他仅与 List 实际有效的代码不兼容 . 那将是可怕的...但现在想象一下,Java大师实际上意识到链接列表对于大多数实际用例来说是可怕的,并且决定切换到他们唯一可用的 List 类的数组列表 . 这会影响世界上每个Java程序的性能,人们不会隐藏实现细节,只能定义抽象 Contract . 这是一个接口的目的:定义一个方法接受什么样的输入,以及期望什么样的输出,而不暴露所有会诱使程序员调整他们的代码以适应可能随任何未来更新而改变的内部细节的内容 .

    接口和具体类之间是一个抽象类 . 它应该有助于实现共享通用或无聊的代码 . 例如, AbstractCollection 提供 isEmpty 的基本实现,基于大小为0, contains 为迭代和比较, addAll 为重复 add ,依此类推 . 这使实现可以专注于区分它们的关键部分:如何实际存储和检索数据 .

    API与SPI

    接口在代码的不同部分之间具有低内聚性 gateways . 它们允许库存在和发展,而不会在内部发生变化时破坏每个库用户 . 它被称为应用程序编程 Interface ,而不是应用程序编程类 . 在较小的规模上,它们还允许多个开发人员通过良好记录的界面分离不同的模块,从而在大型项目上成功协作 .

    假设某些级别的实现细节,抽象类在实现接口时使用高内聚 helpers . 或者,抽象类用于定义SPI,即服务提供者接口 .

    API和SPI之间的区别很微妙,但很重要:对于API,重点在于谁 uses ,而对于SPI,重点在于谁 implements 它 .

    向API添加方法很容易,API的所有现有用户仍将编译 . 向SPI添加方法很难,因为每个服务提供者(具体实现)都必须实现新方法 . 如果接口用于定义SPI,则提供者必须在SPI Contract 发生变化时发布新版本 . 如果使用抽象类,则可以根据现有抽象方法定义新方法,也可以将空方法定义为空 throw not implemented exception 存根,这至少允许旧版本的服务实现仍然可以编译和运行 .

    关于Java 8和默认方法的说明

    尽管Java 8引入了接口的默认方法,这使得接口和抽象类之间的界限更加模糊,但这并不是说实现可以重用代码,而是为了更容易地更改既用作API又用作SPI的接口(或错误地用于定义SPI而不是抽象类) .

    使用哪一个?

    • 该代码的其他部分或其他外部代码应该是 publicly used 吗?添加一个接口,以隐藏公共抽象 Contract 中的实现细节,这是该事物的一般行为 .

    • 这个东西应该有多个实现,有很多共同的代码吗?同时创建一个接口和一个抽象的,不完整的实现 .

    • 是否只有一个实现,没有其他人会使用它?把它变成一个具体的课程 .

    • "ever"很长一段时间,您可以安全地播放它并且仍然在它上面添加一个界面 .

    一个必然结果:反过来常常是错误的:当使用一个东西时,总是尝试使用你真正需要的最通用的类/接口 . 换句话说,不要将变量声明为 ArrayList theList = new ArrayList() ,除非你实际上对它是 array 列表有很强的依赖性,并且没有其他类型的列表会为你剪切它 . 如果's a list, and not any other type of collection doesn'实际上很重要,请使用 List theList = new ArrayList ,甚至 Collection theCollection = new ArrayList .

  • 3

    If you have some common methods that can be used by multiple classes go for abstract classes. Else if you want the classes to follow some definite blueprint go for interfaces.

    以下示例证明了这一点

    Java中的抽象类:

    abstract class animals
    {
        // They all love to eat. So let's implement them for everybody
        void eat()
        {
            System.out.println("Eating...");
        }
        // The make different sounds. They will provide their own implementation.
        abstract void sound();
    }
    
    class dog extends animals
    {
        void sound()
        {
            System.out.println("Woof Woof");
        }
    }
    
    class cat extends animals
    {
        void sound()
        {
            System.out.println("Meoww");
        }
    }
    

    以下是Java中的接口实现:

    interface Shape
    {
        void display();
        double area();
    }
    
    class Rectangle implements Shape 
    {
        int length, width;
        Rectangle(int length, int width)
        {
            this.length = length;
            this.width = width;
        }
        @Override
        public void display() 
        {
            System.out.println("****\n* *\n* *\n****"); 
        }
        @Override
        public double area() 
        {
            return (double)(length*width);
        }
    } 
    
    class Circle implements Shape 
    {
        double pi = 3.14;
        int radius;
        Circle(int radius)
        {
            this.radius = radius;
        }
        @Override
        public void display() 
        {
            System.out.println("O"); // :P
        }
        @Override
        public double area() 
        { 
            return (double)((pi*radius*radius)/2);
        }
    }
    

    简而言之,一些重要的关键点:

    • Java接口中声明的变量默认为final . 抽象类可以包含非最终变量 .

    • 在Java接口中声明的变量默认为static . 抽象类可以有非静态变量 .

    • Java接口的成员默认是公共的 . Java抽象类可以具有类似私有,受保护等类通常的类成员 .

  • 3

    关键点:

    • 抽象类可以包含属性,数据字段,方法(完整/不完整) .

    • 如果方法或属性在abstract关键字中定义,必须在派生类中重写 . (它作为紧密耦合的功能)

    • 如果为抽象类中的方法或属性定义abstract关键字,则无法定义方法体和属性的get / set值,并且必须在派生类中重写 .

    • Abstract类不支持多重继承 .

    • 抽象类包含构造函数 .

    • 抽象类可以包含subs,functions,properties的访问修饰符 .

    • 只有抽象类的完整成员可以是静态的 .

    • 接口只能从另一个接口继承,不能从抽象类继承,抽象类可以从另一个抽象类或其他接口继承 .

    优点:

    • 这是一种强制所有子类进行相同层次结构或标准的 Contract .

    • 如果各种实现属于同一种类并且使用共同的行为或状态,则最好使用抽象类 .

    • 如果我们向抽象类添加一个新方法,那么我们可以选择提供默认实现,因此所有现有代码都可以正常工作 .

    • 它允许快速执行而不是接口 . (接口需要更多时间在相应的类中查找实际方法 . )

    • 它可用于紧密和松散耦合 .

    在这里找到详细信息... http://pradeepatkari.wordpress.com/2014/11/20/interface-and-abstract-class-in-c-oops/

  • 798

    为了给出一个简单但明确的答案,有助于设置上下文:当您不想提供完整实现时,可以使用两者 .

    那么主要的区别是接口根本没有实现(只有没有主体的方法),而抽象类也可以有成员和方法,也可以部分实现 .

  • 23

    我不想强调差异,这些差异已在许多答案中说过(关于接口中变量的公共静态最终修饰符以及对抽象类中受保护的私有方法的支持)

    简单来说,我想说:

    interface:通过多个不相关的对象实现 Contract

    抽象类:在多个相关对象之间实现相同或不同的行为

    来自Oracle documentation

    考虑使用抽象类,如果:

    • 您想在几个密切相关的类之间共享代码 .

    • 您希望扩展抽象类的类具有许多常用方法或字段,或者需要除公共之外的访问修饰符(例如protected和private) .

    • 您想声明非静态或非最终字段 .

    考虑使用接口:

    • 您希望不相关的类实现您的接口 . 例如,许多不相关的对象可以实现 Serializable 接口 .

    • 您希望指定特定数据类型的行为,但不关心谁实现其行为 .

    • 您希望利用类型的多重继承 .

    抽象类与具体类 Build "is a"关系 . interface为类提供"has a"功能 .

    如果您正在寻找 Java 作为编程语言,这里还有一些更新:

    Java 8通过提供 default 方法功能在一定程度上缩小了 interfaceabstract 类之间的差距 . 接口没有方法的实现现在不再有效 .

    有关更多详细信息,请参阅此文档page .

    看看这个SE问题,以便更好地理解代码示例 .

    How should I have explained the difference between an Interface and an Abstract class?

  • 18

    在接口中,所有方法必须只是定义,而不是单个应该实现 .

    但是在抽象类中必须有一个只有定义的抽象方法,但是其他方法也可以在抽象类中实现...

  • 1

    重点是:

    • Abstract is object oriented . 它提供了'object'应具备的基本数据和/或应该能够执行的功能 . 它关注对象的基本特征:它有什么以及它能做什么 . 因此,从同一抽象类继承的对象共享基本特征(泛化) .

    • Interface is functionality oriented . 它定义了对象应具有的功能 . 无论它是什么对象,只要它可以执行界面中定义的这些功能,就可以了 . 它忽略了其他一切 . 对象/类可以包含几个(组)功能;因此,类可以实现多个接口 .

  • 26

    如果要在继承层次结构中提供多态行为,请使用抽象类 .

    当您想要完全不相关的类的多态行为时,请使用接口 .

  • 23

    关于php.net的抽象类和接口的简单而有效的解释:

    接口就像一个协议 . 它没有指定对象的行为;它指定代码如何告诉该对象采取行动 . 接口类似于英语:定义接口定义了代码如何与实现该接口的任何对象进行通信 . 接口始终是协议或承诺 . 当一个类说“我实现接口Y”时,它说“我保证有任何具有接口Y的对象具有相同的公共方法” . 另一方面,抽象类就像是一个部分构建的类 . 它就像一个填空的文档 . 它可能是使用英语,但这并不像某些文档已经编写的那样重要 . 抽象类是另一个对象的基础 . 当一个类说“我扩展抽象类Y”时,它说“我使用了一些已经在另一个名为Y的类中定义的方法或属性” . 所以,请考虑以下PHP:<?php
    类X实现Y {} //这就是说“X”同意用你的代码说“Y” .

    class X扩展Y {} //这就是说“X”将完成部分类“Y” .
    ?>
    如果您正在分发要由其他人使用的类,那么您的类将实现特定的接口 . 界面是一个协议,为您的 class 提供一组特定的公共方法 . 如果您(或其他人)编写了一个已经编写了一些您希望在新类中使用的方法的类,那么您的类将扩展一个抽象类 . 这些概念虽然容易混淆,但却截然不同且截然不同 . 出于所有意图和目的,如果您是任何类的唯一用户,则不需要实现接口 .

  • 5

    我正在建造一个300层的建筑

    建筑的蓝图 interface

    • 例如,Servlet(I)

    建筑物最多可容纳200层 - 部分完工--- abstract

    • 部分实现,例如,泛型和HTTP servlet

    建筑施工完成 - concrete

    • 完全实现,例如,自己的servlet

    接口

    • 我们对实施一无所知,只是要求 . 我们可以去寻找一个界面 .

    • 默认情况下,每个方法都是公共和抽象的

    • 这是一个100%纯抽象类

    • 如果我们宣布公开,我们不能声明私人和受保护

    • 如果我们声明抽象,我们不能声明final,static,synchronized,strictfp和native

    • 每个界面都有public,static和final

    • 序列化和瞬态不适用,因为我们无法在接口中创建实例

    • 非挥发性因为它是最终的

    • 每个变量都是静态的

    • 当我们在接口内声明一个变量时,我们需要在声明时初始化变量

    • 不允许实例和静态块

    抽象

    • 部分实施

    • 它有一个抽象的方法 . 另外,它使用混凝土

    • 抽象类方法修饰符没有限制

    • 抽象类变量修饰符没有限制

    • 我们不能声明除抽象之外的其他修饰符

    • 初始化变量没有限制

    取自DurgaJobs网站

  • 3

    实际上它非常简单 .

    您可以将接口视为一个类,只允许使用抽象方法而不允许其他方法 .

    因此,接口只能“声明”而不能定义您希望该类具有的行为 .

    抽象类允许您同时执行声明(使用抽象方法)以及定义(使用完整方法实现)您希望类具有的行为 .

    普通类只允许您定义,而不是声明您希望类具有的行为/操作 .

    最后一件事,

    在Java中,您可以实现多个接口,但是您只能扩展一个(抽象类或类)...

    这意味着定义行为的继承被限制为仅允许每个类一个...即,如果您想要一个封装了A,B和C类行为的类,您需要执行以下操作:A类扩展B,C类扩展A ..它有点关于多重继承的方式......

    另一方面,接口可以简单地做:接口C实现A,B

    所以实际上Java只在“声明的行为”即接口中支持多重继承,并且只支持具有已定义行为的单继承..除非你按照我描述的方式进行循环...

    希望这是有道理的 .

相关问题