以举例的方式说到如何区分抽象类和接口,这里我们从Java语法谈起,使我们更加了解这两者的内在区别。它们的语法区别:1)接口不能有构造方法,抽象类可以有。2)接口不能有方法体,抽象类可以有。3)接口不能有静态方法,抽象类可以有。4)在接口中凡是变量必须是public static final,而在抽象类中没有要求。
忽然有此一文,是因为同学疑惑道:抽象类居然还有构造方法,又不能直接用来new。我的解释是平时在抽象类中对于构造方法的存在,没有什么印象,是因为IDE默认为你生成了一个无参构造方法,也可以显式地写出构造方法,这个构造方法,是用来被子类调用的,因为任何子类都必须调用从Object开始的所有父亲的构造方法,才算完成初始化工作。那么我引申一下,问他们,接口有构造方法吗?他们的理解,抽象可以有,为什么接口不可以有?!那么在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors。这又何解?
从语法的角度来说,抽象类必须有构造方法,而接口严禁有构造方法,这本身也说明了它们性质的不同。抽象类是一个类,别的类是用关键字 extends 来继承下来,并扩展的,有非常强的is-a的关系,这种关系一般来说符合里氏代换原则。而接口,是被其他类用关键字 implements 来实现接口定义的方法的。如果没什么区别,何必整出两个不同的关键字。 接口只是定义功能和行为规范,如果一个类实现了一个接口,那么这个类必须遵守这个接口的方法约定,但没有is-a的关系。把墙壁上的“小学生行为规范”想象成一个接口,那么是小学生必须遵守这个约定,但小学生不是“行为规范”。
构造方法是用来在对象初始化前对对象进行一些预处理的,提供了实例化一个具体东西的入口。接口只是声明而已,不一定要进行什么初始化,就算要进行初始化,也可以到实现接口的那一些类里面去初始化。接口只是用来表述动作,表述规范来的,可以new一台computer,但我们无法new一个IDE、SATA、PCI、PS-2。因此,接口要构造方法何用?接口是一种规范,被调用时,主要关注的是里边的方法,而方法是不需要初始化的,类可以实现多个接口,若多个接口都有自己的构造器,则不好决定构造器的调用次序,构造器是属于类自己的,不能继承,因为是纯虚的,接口不需要构造方法。而抽象类是具体类的祖先,即使是石器时代,也总要干些初始化的工作,抽象类虽然是不能直接实例化,但实例化子类的时候,就会初始化父类,不管父类是不是抽象类都,都会调用父类的构造方法,初始化一个类,先初始化父类,有没有说初始化接口。
再拿汽车的例子来说明两者的区别,Car, Track, Van 是 Vehicle 抽象类的子类,那么你可以说小娇车是车子,拖拉机是车子,货车是车子。而做为他们共同的父类,会做一些初始化工作,如加汽油、机油、冷却液。另外所有车子具有共同属性,轮子,方向盘,油门等。Brake 是一个刹车动作接口,这个规范要求车子实现了它,必须有能力把速度减到零,只是实现途径不一样,或者是鼓刹,或者是碟刹。或者是效果不一样,有的刹车灵一点,有的刹车差一点。
在抽象类和接口均可以被考虑的地方,接口首先是被提倡使用的,在语法上没有is-a的关系,使用起来更加灵活,另外可以多实现毕竟是一种难得的资源。而抽象类当存在大家共同的实现方法,或者有很多属性操作时,才是首选,当考虑使用抽象类时,在可预见的未来,它要体现出被继承时非常强烈的is-a关系。
接口不能有方法体,就是强制接口定义者不能给接口增加一些详细的实现,指定的必须是纯虚的接口,对于架构者来说,它需要做的就是定义一个可以理解的接口名,参数列表,以及返回类型。而抽象类是可以有自己的实现方法,这个方法可以被用来被执行。有时候,我们会误以为抽象类中的方法不能用super显示调用,因为super是指代父类对象,而抽象类MS不能有对象。但事实上可以,任何子类实际的对象,都可以理解成父类的对象。
接口的所有方法都是抽象的,而抽象方法是没有static,有static的方法是不能override的,不能实现多态,所以这样定义接口才有意义,接口中定义的方法目的很明确:就是给实现类去实现,如果你在接口中将方法声明为静态的(与具体的实例无关),但接口中的方法又要求必须被实现类去实现(可能会有多个实现类),这岂不是自相矛盾!如果硬要加上static上去,编译器会友好提示:Illegal modifier for the interface method FF.f(); only public & abstract are permitted。说到底,不能再加任何除public 和 abstract 的任何修饰符了,如:private, protected, final, static.
数据成员没有多态的概念,只有可不可以被访问的说法,如果是公有的数据成员是在任何地方都可以被访问和修改的,那么接口定义的数据成员如果是私有的,又何必定义,因为它没有方法,就是说没有任何方法对这个数据成员可以操作。如果是公有的,谁都可以修改,那么,多重实现多个接口,这个数据不是改得乱了套?所以接口一般不允许有数据成员,但如果真的有,明确默认即为public final static, 严格保证对于所有实现者来说只有一份原始的数据。
那么在架构设计时,如何使用抽象类和接口来解决问题,是一个非常复杂的问题,抽象类更侧重于归纳同一父类的子类的共同特征,如果属性,方法;接口更侧重于定义任意的类有没有相同语义的方法,它是一个一经定义不轻易更改的规范,它的修改在项目中,往往是动一发而牵全身,即使有考虑不周到的地方,也会使用新增接口的形式去弥补。其实abstract class表示的是"is-a"关系,interface表示的是"like-a"关系。最顶级的是接口,然后是抽象类实现接口,最后才到具体类实现。

转载于:https://www.cnblogs.com/mike-JP/p/10962555.html

接口为什么不能有构造函数相关推荐

  1. 【Kotlin】接口 ( 声明 | 实现 | 接口方法 | 接口属性 | 接口覆盖冲突 | 接口继承 )

    文章目录 I . 接口总结 II . 接口声明 III . 接口实现 IV . 接口中的方法 V . 接口中的属性 ( 变量 / 常量 ) VI . 接口中的属性属性覆盖 ( 变量 / 常量 ) VI ...

  2. typescript 接口 java_[Java教程]【TypeScript】TypeScript 学习 2——接口

    [Java教程][TypeScript]TypeScript 学习 2--接口 0 2015-06-19 12:00:28 在 TypeScript 中,接口是用作约束作用的,在编译成 JavaScr ...

  3. interface-C#接口-统一的标准

    文章目录 接口的定义 接口的实现 实例1 实例2 接口的继承 博主写作不容易,孩子需要您鼓励 万水千山总是情 , 先点个赞行不行 接口是面向对象编程的一个重要技术,在C#中负责实现多重继承.一个接口定 ...

  4. socket 编程入门教程(一)TCP server 端:4、构造函数涉及的概念

    话题回到"黑社会办公室"的例子,讲概念已经扯得比较远了,不过,这一节我们还得讲概念,不过好在有些程序的例子.如果大家不想翻回去看TcpServer类的原型,我这里直接给出这个头文件 ...

  5. TS Interface(接口)

    接口(Interface) 用来建立某种代码约定,使得其它开发者在调用某个方法或者创建新的类时,必须遵循接口所定义的代码约定 接口的前面加了一个 I 字母 规范 在代码设计中,接口是一种规范: 接口通 ...

  6. java接口构造方法吗_Java中抽象类和接口中有构造方法吗?

    Java中抽象类和接口中有构造方法吗? ①在接口中 不可以有构造方法 在接口里写入构造方法时,编译器提示:Interfaces cannot have constructors. A. 构造方法用于初 ...

  7. Java千百问_05面向对象(004)_java接口到底是什么

    1.什么是接口 接口(interface)不是一个类,它是抽象方法的集合.一个类实现一个接口,从而继承和实现接口的抽象方法.  抽象方法看这里:java中抽象概念如何体现的 接口的特点如下,先看与类类 ...

  8. C#编程(二十五)----------接口

    接口 如果一个类派生自一个接口,声明这个类就会实现某些函数.并不是所有的面向对象的语言都支持接口. 例如,有一个接口:IDispoable,包含一个方法Dispose(),该方法又类实现,用于清理代码 ...

  9. 读书笔记 effective c++ Item 41 理解隐式接口和编译期多态

    1. 显示接口和运行时多态 面向对象编程的世界围绕着显式接口和运行时多态.举个例子,考虑下面的类(无意义的类), 1 class Widget { 2 public: 3 Widget(); 4 vi ...

  10. ts讲解(接口interface)

    介绍 官网是这样定义的: TypeScript的核心原则之一是对值所具有的结构进行类型检查. 它有时被称做"鸭式辨型法"或"结构性子类型化". 在TypeScr ...

最新文章

  1. 第五百六十四天 how can I 坚持
  2. StanFord ML 笔记 第四部分
  3. 第三周项目四-穷举法解决组合问题
  4. shiro如何保证session不失效_请问在不加锁的情况下如何保证线程安全?
  5. 初级图像混合——线性混合操作
  6. redis源码剖析(三)——基础数据结构
  7. 为什么数据结构不用java_泛谈Java中的不可变数据结构
  8. php与mysql网页实例,php与mysql 实例
  9. Web Hacking 101 中文版 十五、代码执行
  10. 网络流之最小点权覆盖和最大点权独立集学习
  11. Docker视频教程 之 熟悉docker-machine及docker常用命令 - 知识林
  12. 孤儿进程与僵尸进程产生及其处理
  13. 多线程编程中条件变量和虚假唤醒(spurious wakeup)的讨论
  14. noip2005 篝火晚会
  15. TD式创新:中国标准横空出世 回归主流的TDD LTE
  16. python数据分析多元 线性回归
  17. 【jzoj5289】【NOIP2017提高组A组模拟8.17】【偷笑】【数据结构】
  18. Web前端期末大作业-写真摄影工作室网页设计(HTML+CSS+JS)
  19. 周轶璐教授:服务好医生,如何更全面地了解数据、利用数据?
  20. Neo4j CQL 常用语句

热门文章

  1. 豪横!1.3 亿的数据毫秒级???居然做到了!!!
  2. 不想一直做码农的请进~
  3. 快来,前方美女出没!!
  4. 架构师重构代码的12条军规
  5. 你整明白了吗?Linux Shell 中各种括号的作用 ()、(())、[]、[[]]、{}
  6. Git版本控制及远程仓库的使用
  7. shell基础之99乘法表
  8. [转]MySQL修改root密码的多种方法
  9. 服务端Latex解析成图片或者HTML或者SVG方案
  10. ADB命令行工具使用