接口的诞生


接口其实就是一种标准一种规范。

先从生活中的例子讲起,理解含义和概念后,再去理解程序会更容易理解一些。

生活中接口无处不在,比如著名的USB接口,大家可以试想一下,如果没有像USB这种统一的标准我们会有多麻烦。

拿电脑端来举例:



这台电脑只有A 接口,另一台电脑只有B 接口,一万台电脑就可以有一万个接口,那你该怎么去买数据线?

就算买了数据线,也只能用在一台电脑上换一个电脑就完全没用了。

而这只是数据线的其中一头,另一头的接口也没统一呢。

比如手机接口也不统。一万个手机就有一万个接口,这该有多麻烦。现在安卓和苹果,不能互用充电线,我们都觉得麻烦了,真要一个手机一种接口,那只怕心态崩了。如果没有一个统一的标准,那无论对设备厂商,还是对我们用户来说,都非常痛苦。所以统一标准和制定规范一定是各行各业都需要做也都想做的事情,那这个标准和规范就可以理解为接口。生活中的例子讲完,我们来延申到程序。

每项技术的产生,肯定是有其原因的。理解了技术的诞生经过,一般也就理解了技术本身。

那接口是如何诞生的呢?



假设现在是一个没有对象,只有基本数据类型和函数的世界,当我们的数据和函数多了维护起来就越发困难

于是我将其中一些有关联性质的数据和函数封装了起来,类和对象就这么诞生了,我只需要创建一个对象就拥有了特定的属性和方法,这些属性和方法都聚合在了一个实例上,维护起来比较方便。可还有一个问题,现在大多数类的属性和方法都差不多,完全没必要每次重新定义

于是乎我将这些重复的东西封装到一个类中,其他子类只需要复用它即可,继承就这么诞生了,子类继承父类之后,便拥有了父类的属性和方法,同时可以扩展自己的特性。



我们经常指定一个父类然后接收多个子类,在程序执行的时候,能自行发挥各种子类自己的特性,这一机制就是之前讲过的多态,很多时候我们发现父类完全没必要实现所有逻辑,也没必要创建父类对象,因为我们就是想让各种各样的子类来完成不同的逻辑。



这时候我们就可以将,父类的方法抽象出来,抽象类就这么诞生了,这里的抽象类其实已经有了标准和规范的意思,抽象方法就可以理解为一个对外的标准,子类就是这些标准的实现方,然后我们会发现,抽象类还不算彻底的抽象,因为它除了抽象方法外,还有成员属性,可我们很多时候,就是想指定一个纯粹的标准,让子类只去实现抽象方法,不想让子类再去继承别的东西。

于是乎我们将抽象类更进一步的抽象,接口就这么诞生了,接口只有方法没有成员属性,子类继承接口后,唯一能做的就是重写方法,所以说接口就是一种标准一种规范,它规定号方法模板后,子类都得按照这个来实现。说到这大家应该就能体会到接口在程序中的作用,就是定义方法让子类实现,然后供调用方调用。

映射到生活中子类就是设备厂商,接口调用方就是我们用户,只管使用,而不用操心各个设备的差异,概念性和比喻的东西讲完了,再来讲一讲,接口在程序中的具体运用:当我们想操作多个拥有共性的对象时,就可以用到接口

比如:我想打印一个数据集

    public static void printConllection(Collection collection){
if(collection == null){
return;
}
System.out.println("数据数量"+ collection.size())
System.out.println("数据"+ collection.size())
} public static void main(String[] args){
printCollection(new ArrayList());
PrintCollection(new HashSet());
}

就可以用到Java 的Collection接口,我将方法参数定义成Collection 别人就可以传任何 Collection 的子类进来了,ArrayList 可以,HashSet也可以,根本不用关心,数据是用哪个集合来存储的,Collection 有上百个子类别人爱用哪个用哪个,都不会影响到我的打印逻辑,就好像USB接口定义好后,你插U盘也好,手机充电线也好,这就是我们常说的面向接口开发

抽象类和接口的异同


首先我们知道抽象类和接口都是为了将方法进行抽象,然后让子类去实现

    public abstract class Animal{
public abstract void eat();
} public interface Runnable{
public abstract void run();
}

所以可以定义抽象方法就是这者第一个相同点。

在接口诞生中说过,这种类是没有必要创建实例对象的,所以第二个相同点就是不能创建本类对象,只能由子类去实例化子类对象。

两者最为明显的一个差异点,就是子类要扩展它们时使用的关键字不同,称呼不同但本质一样

// 继承抽象类
public class Dog extends Animal{} // 实现接口
public class Thread implements Runnable {}

然后时抽象类可以去实现接口,而接口只能继承接口,不能继承类

public abstract class Animal implements A{}

public interface Runnable extends A,B,C{}

同时一个类最多只能继承一个父类,但可以实现多个接口。

public abstract class pet extends Animal implements A,B,C {}

所以当我们发现既可以用抽象类也可以用接口时,尽量去选择接口,这样子类的灵活度会更高

在接口的诞生我们说过,抽象类更进一步地抽象后就诞生了接口,接口比抽象类更纯粹,因为它没有成员属性,只有方法,子类实现接口后,唯一能做的就是重写方法,不像抽象类,子类继承抽象类后,连带父类的成员属性一起继承了。

  public abstract class Animal {
protocted String name; public abstract void eat();
} public interface Runnable {
public static final String CRAB = "螃蟹"; public abstract void run();
}

抽象类可以定义成员属性,而接口不能定义成员属性,只能定义静态属性,而且只能用final 关键字定义静态常量,不能定义静态变量,接口还没有构造器,可以说是非常的纯粹了。

说白了接口就是一个只有方法和静态常量的类

这里有人可能会疑惑,抽象类都不能被实例化,还要个构造器有啥用,它的用处是限定子类的构造行为。

比如:抽象类可以将构造器定义好几个参数,子类要想实例化则必须想办法传入这几个参数

    public abstract class Animal{
protected String name;
protected Animal(String name){
this.name=name;
} public abstract void eat();
} class Dog extends Animal{
public Dog(String name) {
super(name);
} @Override
public void eat() {
System.out.println(name + "要开吃了~");
}
}

两者异同就说完了,额外说明一些版本之前的差异

其实接口在Java8 之前更加纯粹,那时接口只能定义抽象方法,不能自己实现方法,也不能定义静态方法,到了Java 8才可以定义静态方法以及可以用 default 关键字来实现方法,这里不要死记硬背,一定要去理解 Java 设计者背后的意图,为什么突然在Java 8就加了这个特性呢?因为Java 8 许多原有的接口,新增了很多方法,这些新增的方法会影响到之前的子类如果你继承了某个接口,突然接口新增了一个方法,而你没有去实现,你的子类就会编译失败,为了保证向下兼容性,Java 8就推出了default关键字,被default关键字修饰的方法就不是抽象方法了,也就不会强制要求已有的子类去实现方法,default方法出现后,大家发现还挺好用,就大量在接口中去实现一些默认逻辑,可是一个方法中实现复杂逻辑,就会导致代码难以维护,于是Java 9又推出了一个新特性,那就是能在接口中,定义private 方法,这样就可以将一些内部逻辑拆开了,可以发现越到后面抽象类和接口的差异也就越小。

总结

抽象类(abstract class) 接口(interface)
定义 包含抽象方法的类 主要是抽象方法和静态常量的类
组成 构造器、抽象方法、普通成员方法、成员变量、静态方法、静态常量、常量 静态常量、抽象方法、default 方法、静态方法(Java8)私有方法(Java9)
使用 子类继承抽象类(extends) 子类实现接口(implements)
关系 子类只能继承一个抽象类,抽象类可以实现多个接口 子类可以实现多个接口,接口不能继承类,但可以继承多个接口
选择 如果需要继承父类的成员变量,或需要控制子类的实例化,则选抽象类 优先选择接口,避免单继承的局限性

【JavaSE】抽象类、接口的更多相关文章

  1. 速战速决 (4) - PHP: 类基础, 抽象类, 接口, trait

    [源码下载] 速战速决 (4) - PHP: 类基础, 抽象类, 接口, trait 作者:webabcd 介绍速战速决 之 PHP 类基础 抽象类 接口 trait 示例1.类的相关知识点 1(基础 ...

  2. python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)

    一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...

  3. python面向对象 : 抽象类(接口类),多态,封装(私有制封装)

    一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...

  4. 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装

    抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...

  5. “全栈2019”Java第一百零六章:匿名内部类与抽象类接口注意事项

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  6. 面向对象 继承 抽象类 接口 static 权限修饰符

    Day01 面向对象 继承 抽象类 接口 static 1.匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. 2.类的继承是指在一个现有类的基础上去构建一个新的类,构建出 ...

  7. python day - 19 抽象类 接口类 多态 封装

    一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...

  8. C# 你什么让程序员寂寞成酱紫 (男生版 娱乐中学习 抽象类 接口 继承 实现方法 )

    你什么让程序员寂寞成酱紫 (男生版 娱乐中学习 抽象类 接口 继承 实现方法 )   一个家庭 相当于 一个空间,这个空间里 有 很多元素,比如 爱,爱这个抽象事物,可能有很多动作,接吻.交流,对于一 ...

  9. 13. 抽象类 & 接口

    一.抽象类 // 抽象类Shape public abstract class Shape { // 1. 成员变量 private String color; // 2. 初始化块 { System ...

  10. 面向对象的理解 抽象类&接口

    一.关于面向对象 1.什么是面向对象     在解释面向对象之前,先说说面向过程.学过C的同学都知道,C就是面向过程的一种语言.那什么是面向过程呢?比方说组装主机,对于面向过程,需要从0开始.买cpu ...

随机推荐

  1. 重构、插件化、性能提升 20 倍,Apache DolphinScheduler 2.0 alpha 发布亮点太多!

    点击上方 蓝字关注我们 社区的小伙伴们,好消息!经过 100 多位社区贡献者近 10 个月的共同努力,我们很高兴地宣布 Apache DolphinScheduler 2.0 alpha 发布.这是 ...

  2. what the difference betweent pin page and lock page ?

    以前在项目中,大家为了避免自己使用的page被换出,使用的方式是mlock,从mlock的实现的看,它限制了page被swap, 然后在一个swap off的系统中,这样其实和mlock调用与否没有关 ...

  3. CF-1623C

    Problem - 1623C - Codeforces 题意: 给出一个序列,从第三个数字开始,你可以让他减少3*d,然后让它的前两个数字,分别加2*d,和d,找出序列中的最小值的最大值. 题解: ...

  4. 《吐血整理》进阶系列教程-拿捏Fiddler抓包教程(17)-Fiddler如何充当第三者,再识AutoResponder标签-下篇

    1.简介 上一篇宏哥主要讲解的一些在电脑端的操作和应用,今天宏哥讲解和分享一下,在移动端的操作和应用.其实移动端和PC端都是一样的操作,按照宏哥前边抓取移动端包设置好,就可以开始实战了. 2.界面功能 ...

  5. KingbaseES V8R6C5禁用root用户ssh登录图形化部署集群案例

    案例说明: 对于KingbaseES V8R6C5版本在部集群时,需要建立kingbase.root用户在节点间的ssh互信,如果在生产环境禁用root用户ssh登录,则通过ssh部署会失败:在图形化 ...

  6. Oracle_FDW 使用介绍

    本文以例子的形式介绍 KingbaseES(Postgresql)数据库如何通过 oracle_fdw 扩展访问Oracle数据库.以下例子在PG12.3 与 KingbaseES V8R6进行过实际 ...

  7. 聊聊两个Go即将过时的GC优化策略

    转载请声明出处哦~,本篇文章发布于luozhiyun的博客:https://www.luozhiyun.com 这篇文章本来是要讲 Go Memory Ballast 以及 Go GC Tuner 来 ...

  8. null和undefined的区别、数组和伪数组的区别

    null和undefined的区别 undefined: 字面意思是未定义的值,语义是希望表示一个变量最原始的状态,而非人为操作的结果.这种原始状态会在以下四个场景中出现: 声明了一个变量但没有赋值 ...

  9. Elasticsearch:用户安全设置

    Elastic Stack的组件是不安全的,因为它没有内置的固有安全性. 这意味着任何人都可以访问它. 在生产环境中运行Elastic Stack时,这会带来安全风险. 为了防止生产中未经授权的访问, ...

  10. flask中验证用户登录的装饰器

    from flask import Flask,render_template,redirect,request,session from functools import wraps app = F ...