【JavaSE】抽象类、接口
接口的诞生
接口其实就是一种标准一种规范。
先从生活中的例子讲起,理解含义和概念后,再去理解程序会更容易理解一些。
生活中接口无处不在,比如著名的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】抽象类、接口的更多相关文章
- 速战速决 (4) - PHP: 类基础, 抽象类, 接口, trait
[源码下载] 速战速决 (4) - PHP: 类基础, 抽象类, 接口, trait 作者:webabcd 介绍速战速决 之 PHP 类基础 抽象类 接口 trait 示例1.类的相关知识点 1(基础 ...
- python 全栈开发,Day21(抽象类,接口类,多态,鸭子类型)
一.昨日复习 派生方法和派生属性 super 只有在子父类拥有同名方法的时候, 想使用子类的对象调用父类的方法时,才使用super super在类内 : super().方法名(arg1,..) 指名 ...
- python面向对象 : 抽象类(接口类),多态,封装(私有制封装)
一. 抽象类(接口类) 与java一样, python也有抽象类的概念但是同样需要借助模块实现,抽象类是一个特殊的类, 它的特殊之处在于只能被继承, 不能被实例化. 从设计角度去看, 如果类是从现实对 ...
- 【学习笔记】--- 老男孩学Python,day18 面向对象------抽象类(接口类), 多态, 封装
抽象类,接口类 Python没有接口这个概念 抽象类(接口类): 目的是制定一个规范 要学会归一化设计,有重复的东西就要想把它们合并起来 from abc import ABCMeta, abstra ...
- “全栈2019”Java第一百零六章:匿名内部类与抽象类接口注意事项
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 面向对象 继承 抽象类 接口 static 权限修饰符
Day01 面向对象 继承 抽象类 接口 static 1.匿名对象是指创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量. 2.类的继承是指在一个现有类的基础上去构建一个新的类,构建出 ...
- python day - 19 抽象类 接口类 多态 封装
一. 抽象类接口类即制定一个规范 特点: 1.不可被实例化. 2.规范子类当中必须事先某个方法. 3.在python中有原生实现抽象类的方法,但没有原生实现接口类的方法. 例题:制定一个规范就是,子类 ...
- C# 你什么让程序员寂寞成酱紫 (男生版 娱乐中学习 抽象类 接口 继承 实现方法 )
你什么让程序员寂寞成酱紫 (男生版 娱乐中学习 抽象类 接口 继承 实现方法 ) 一个家庭 相当于 一个空间,这个空间里 有 很多元素,比如 爱,爱这个抽象事物,可能有很多动作,接吻.交流,对于一 ...
- 13. 抽象类 & 接口
一.抽象类 // 抽象类Shape public abstract class Shape { // 1. 成员变量 private String color; // 2. 初始化块 { System ...
- 面向对象的理解 抽象类&接口
一.关于面向对象 1.什么是面向对象 在解释面向对象之前,先说说面向过程.学过C的同学都知道,C就是面向过程的一种语言.那什么是面向过程呢?比方说组装主机,对于面向过程,需要从0开始.买cpu ...
随机推荐
- MyBatis 02 配置
导入jar包 <dependency> <groupId>org.mybatis</groupId> <artifactId>mybatis</a ...
- Pycharm5个非常有用的技巧
PyCharm 是一款非常强大的编写 python 代码的工具.掌握一些小技巧能成倍的提升写代码的效率,本篇介绍几个经常使用的小技巧. 一.分屏展示 当你想同时看到多个文件的时候: 右击标签页: 选择 ...
- 使用idea remote 开发体验
本地使用idea开发最不好的一个体验就是打开稍大的工程就非常的卡,怎么调参数都没用,现在idea推出了idea remote就赶紧来体验下. 使用方式 除了idea不需要额外下载什么包,但是因为rem ...
- Configuration的学习
创建 //1.创建,调用的空惨 Configuration conf = new Configuration(); 加载主配置 //2.读取主配置文件==>如果是空参方法则自动加载sec下的re ...
- 一种比css_scoped和css_module更优雅的避免css命名冲突小妙招
css_scoped 与 css_module 我们知道,简单的class名称容易造成css命名重复,比如你定义一个class: <style> .main { float: left; ...
- DS
树状数组 原始问题 \(a_x \overset+\gets y\) \(\sum\limits_{i=1}^{r} a_i\) 解决方法: 定义 \({\rm lb}(i) = i-i \wedge ...
- kingbaseES R3 集群备库转换为单实例库案例
案例说明: 在生产环境需要将集群中架构转换为单实例环境,本案例以备库转换为单实例库为案例,介绍了两种方案,一种在数据库数据量小的环境下采用 sys_dumpall 导出导入方式建立单实例库:另外一种是 ...
- LyScript 内存扫描与查壳实现
LyScript 中提供了多种内存特征扫描函数,每一种扫描函数用法各不相同,在使用扫描函数时应首先搞清楚他们之间的差异,如下将分别详细介绍每一种内存扫描函数是如何灵活运用的,最后将实现一个简易版内存查 ...
- spring native 初体验实现 小米控制美的空调
目前关于 spring native 分享的文章还比较少 写这篇文章的主要目前是分享一下自己写的一个 小米控制美的空调 的程序 集成 spring native 过程中碰到的一些问题和解决方法 先放地 ...
- imread opencv
''' Mat cv::imread ( const String & filename, int flags = IMREAD_COLOR ) Python: retval = cv.imr ...