【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 ...
随机推荐
- 微信小程序创建组件的流程,以及组件 properties 和 slot
组件定义流程 1)为了方便管理组件文件,创建一个目录来存放组件(可省略该步骤) 组件与页面都有相同的配置,包括的文件有:wxml.wxss.js.json 四个文件. 2)编写组件 编写组件与编写页面 ...
- Java对象已死吗 深入理解Java虚拟机笔记
1.引用计数器法 给每个对象设置一个计数器,每当有一个引用就给计数器的值+1,引用时小时就减一,当计数器值为0是就可以回收掉了. 主流虚拟机都没有使用这种算法,循环依赖问题 2.可达性分析: 思路是通 ...
- Silk语言-中国人自己的开源编程语言
什么是Silk Silk语言是一门完全独立自主开发的跨平台动态类型编程语言,绝非"木兰"等套壳语言. Silk简单易学,30分钟即可掌握全部语法,让你像Python一样简单地写C/ ...
- java数组---初始化
public class ArrayDemo { public static void main(String[] args) { int[] a={1,2,3,4,5,6,7,8,9}; //静态初 ...
- [Golang] cgo 调用 .so 捕获异常问题
最近需要在 go 中去调用 .so 库去完成一些事情,go 方面,利用 cgo 可以顺利的调用 .so 中的方法,但是有个问题是 go 没法捕获 .so 那边出现的异常.如果 .so 那边异常了,那么 ...
- 「学习笔记」倍增思想与lca
目录 ST表 算法 预处理 查询 关于 log2 Code 预处理 查询 例题 P2880 P2048 lca 树上 RMQ 前置知识:欧拉序列 算法 Code 离线 Tarjan 算法 Code 倍 ...
- SpringMVC 03: 请求和响应的乱码解决 + SpringMVC响应Ajax请求
请求或响应的中文乱码问题 tomcat9解决了get请求和响应的中文乱码问题,但是没有解决post请求或响应的中文乱码问题 tomcat10解决了get和post请求以及响应的中文乱码问题 考虑到实际 ...
- Rsync数据备份工具
Rsync数据备份工具 1.Rsync基本概述 rsync是一款开源的备份工具,可以在不同主机之间进行同步(windows和Linux之间 Mac和 Linux Linux和Linux),可实现全量备 ...
- 第二章 Kubernetes快速入门
一.四组基本概念 Pod/Pod控制器: Name/Namespace: Label/Label选择器: Service/Ingress. 二.Pod/Pod控制器 2.1 Pod Pod是K8S里能 ...
- Java开发学习(三十)----Maven聚合和继承解析
一.聚合 分模块开发后,需要将这四个项目都安装到本地仓库,目前我们只能通过项目Maven面板的install来安装,并且需要安装四个,如果我们的项目足够多,那么一个个安装起来还是比较麻烦的 如果四个项 ...