目录
一、抽象
1、概念
一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就是抽象类
理解: 就是将一个 多种类 的共同点 抽象出 到一个类中
抽象类的关键字:abstract 修饰
抽象类: abstract class 类名{}
抽象方法:public abstract void 方法(); //抽象方法没有方法体,没有大括号
注意:
一个抽象类中 可以有普通成员方法,也可以有抽象方法,但是只要有抽象方法,这个必须是抽象方法
//抽象类
abstract class Shape{
//普通成员
public String name;
//抽象方法
abstract void draw();
//普通成员方法
public void priName(){
System.out.println(name);
}
}
//菱形
class Rect extends Shape {
//重写抽象方法,继承抽象类 必须实现抽象方法
@Override
public void draw() {
System.out.println("◇");
}
}
2、抽象类的特点
- 抽象类 被 abstract 修饰
- 抽象类不能被实例化,抽象类就是被继承的
- 抽象类 即可以有 抽象方法,也可以有 非抽象方法,
- 抽象类 也可以有 构造方法 ,子类创建对象时,初始化父类成员变量
- 抽象方法 ,被 abstract 修饰,没有具体的实现,一个类只要有抽象方法,必须是抽象类
- 抽象方法 不能被 private , final,static 修饰,因为抽象方法要被子类重写
- 子类继承了抽象类,必须对被继承的抽象方法重写,不实现则这个子类也是抽象类被 abstract 修饰
- 抽象类继承另一个抽象类,可以不重写(实现)其中的抽象方法,交由它具体的子类来实现
注意:
- private 冲突 abstract的方法必须被子类重写,而private不能被继承
- final 冲突 final修饰的方法,变量不能修改,abstract修饰的方法必须被重写
- static 不能共存 无意义 static 是静态的,abstract方法中无方法体,无法调用
3、抽象的作用
抽象类本身不能被实例化, 要想使用, 只能创建该抽象类的子类. 然后让子类重写抽象类中的抽象方法.
那么 普通类也可以被继承,普通的方法也可以被重写呀, 为啥非得用抽象类和抽象方法呢?
确实如此. 但是使用抽象类相当于多了一重编译器的校验,机器的校验,比人更及时准确;
使用抽象类的场景就如上面的代码, 实际工作不应该由父类完成, 而应由子类完成. 那么此时如果不小心误用成父类了, 使用普通类编译器是不会报错的. 但是父类是抽象类就会在实例化的时候提示错误, 让我们尽早发现问题.
二、接口
1、概念
接口就是公共的行为规范标准,大家在实现时,只要符合规范标准,就可以通用。
在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
可以看做 抽象类的 plus
2、语法
- 接口 关键字: interface 修饰 public interface 接口名{}
- 类 实现接口 :implements public class 类名 implements 接口{}
注意:
- 创建接口时,接口的命名一般以大写字母 I 开头
- 接口的命名 一般用”形容词“词性的单词
- abstract 可以修饰 接口
- 阿里编码规范中约定, 接口中的方法和属性不要加任何修饰符号, 保持代码的简洁性
3、接口的使用
接口不能直接使用,必须要有一个"实现类"来"实现"该接口,实现接口中的所有抽象方法。
接口类
public interface IUSB {
//功能
//开
void openDevice();
//关
void closeDevice();
}
鼠标类 接口 USB
//鼠标类 接口 USB
public class Mouse implements IUSB{
@Override
public void openDevice() {
System.out.println("打开鼠标");
}
@Override
public void closeDevice() {
System.out.println("关闭鼠标");
}
//自己的功能
public void click(){
System.out.println("鼠标点击");
}
}
键盘类 接口 USB
//键盘类 接口 USB
public class KeyBoard implements IUSB{
@Override
public void openDevice() {
System.out.println("打开键盘");
}
@Override
public void closeDevice() {
System.out.println("关闭键盘");
}
//
public void inPut(){
System.out.println("键盘输入");
}
}
只要 一个类实现了 接口 USB 都可以链接上电脑,并使用
//电脑类 使用USB接口类
public class Computer {
public void powerOn(){
System.out.println("电脑开机");
}
//
public void powerOff(){
System.out.println("电脑关机");
}
//外接 USB
public void useDevice(IUSB usb){
//开机
usb.openDevice();
//鼠标类
if(usb instanceof Mouse){
Mouse mouse = new Mouse();
//点击
mouse.click();
}else if (usb instanceof KeyBoard){
KeyBoard keyBoard = new KeyBoard();
//输入
keyBoard.inPut();
}
//关闭
usb.closeDevice();
}
}
创建 电脑 Computer类就可以实现不同 USB接口类,后续的功能添加和删除也很方便
public class TestUsb {
public static void main(String[] args) {
Computer computer = new Computer();
//开机
computer.powerOn();
System.out.println("=============");
//使用鼠标设备
computer.useDevice(new Mouse());
System.out.println("=============");
//使用键盘设备
computer.useDevice(new KeyBoard());
System.out.println("=============");
//关机
computer.powerOff();
}
}
4、接口的特性
- 接口类型是一种引用类型,但是不能直接 new 接口对象
- 接口中的成员变量 只能是常量(直接初始化),直接通过接口名称访问 成员变量 — 默认修饰符:public static final
- 接口中每一个方法都是 public 的抽象方法,即都是被隐藏的 public abstract 修饰(被其他的修饰符修,会报错),可以不用写出来 方法 ---- 默认修饰符:public abstract
- 接口中可以有 static 方法,jdk8中:接口中还可以包含default方法。
- 接口中的方法没有实体,只能被 实现接口的类实现,使用关键字:implements
- 重写接口中的方法,不能使用默认的访问权限(public),加上public,实现接口的重写方法不能 比接口的方法权限低
- 接口不能有 静态代码块 和 构造方法
- 接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
- 如果类没有实现接口中的所有的抽象方法,则类必须设置为抽象类
5、类 与 接口的关系
- 类与类 — 继承关系:Java中不支持多继承,但是一个类可以实现多个接口。
- 类与接口 — 实现关系:一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。(如果多接口 有同名抽象方法,只重写一次)
- 接口与接口 — 继承关系:接口可以继承一个接口或多个接口(逗号隔开), 达到复用的效果. 使用 extends 关键字.
//跑
interface IRuning{
void run();
}
//飞
interface ISwimming{
void swimming();
}
//两栖动物 外接(继承) 两个接口
interface IAmphibious extends IRuning,ISwimming{
//可以不实现 实现类 必须实现接口方法
}
//鸭 实两栖动物
//class Duck implements IRuning,ISwimming{ //也可以直接实现多个接口
class Duck implements IAmphibious{
public String name;
public Duck(String name) {
this.name = name;
}
//重写
@Override
public void run() {
System.out.println(name + "正在跑");
}
//重写
@Override
public void swimming() {
System.out.println(name + "正在游泳");
}
}
public class Test {
public static void main(String[] args) {
Duck duck = new Duck("唐老鸭");
duck.run();
duck.swimming();
}
}
//唐老鸭正在跑
//唐老鸭正在游泳
6、抽象类和接口的区别
核心区别:
- 抽象类 中可以包含普通成员和不同方法,不用重写;
- 接口类 不能包含普通成员和不同方法,子类必须重写所有 抽象方法
区别 | 抽象类(abstract) | 接口(interface) |
结构组成 | 普通类 + 抽象方法 | 抽象方法 + 全局变量 |
权限 | 默认、public、proteced | public |
子类使用 | 使用 extends 关键字继承 | 使用 implements 关键字实现接口 |
关系 | 一个抽象类可以实现若干接口 | 接口不能继承抽象类,但 接口能用 extends 关键字继承多个 父接口 |
子类限制 | 一个子类只能继承一个抽象类 | 一个字类可以实现多个接口 |