接口 与 抽象Interface and Abstract

变量类型 与 权限

通过变量类型访问对象方法

Person 访问 Person

通过同类型对象变量访问

1 2 3
Person person = new Person();person.eat();person.work();
Animal 访问 Person

通过父类型对象变量访问

1 2 3!
Animal animal = new Person();animal.eat();animal.work();

项目进度推进

attack 方法消除

功能期待

有 attck 就调用 没有 attack 就不调用

一个新的变量类型,仅有 attack 方法,不多不少

接口 x 向上转换

案例

定义接口

什么是 接口

一个变量类型,用于通过它访问对象

在这个类型里所声明的方法,将来就可以访问

方法声明
1 2 3
public interface Calculator { void calculate();}
接口内的方法 默认 public

接口内只能有方法声明

必须 public 所以不需要写 public

接口内的方法不能写实现

仅仅声明, 所以不能写方法实现

接口不可以被 new

接口仅用于对访问进行控制,并不是对象,所以不能被 new

接口不可以属性声明

接口用于描述一套调用的方法,类似方法组

所以不能声明属性

之后会学习到,可以在接口内声明静态属性

类与接口对接

实现声明
1
public class 类名 implements 接口名public class Person implements Calculator
名词

类 实现 接口

接口 / 实现类

效果

声明 implements 接口后,就可以使用 接口作为变量类型,访问对象

1 2
Calculator c = new Person();c.calculate();
类实现接口方法

声明 implements 接口后,这个类必须确保有覆盖这个方法,

也就是对方法进行实现

向上转换

只能调用接口里声明的方法

向上转换、减少保障、降低权限、更多可能

接口 x 调用保障

调用保障分析

接口如何做到可以安全的调用到对应的代码?

1.

对象必须声明实现接口

2.

声明实现接口的类,必须实现接口里所有的方法

接口 x 多态Interface x Polymorphism

多态现象

对同样的对象变量类型 调用 同样的方法

却执行了不一样的代码

多态思维

类型不确定性

调用方

不能确定 到底调的是具体哪个类

也不需要 知道是哪个类

效果不确定性

调用方

不能确定 到底调的是具体哪个方法

也不需要 知道是哪个方法

接口 x 类型转换

instanceof 实质

1 2 3
if (person instanceof Calculator){ ...}

instanceof 用来探测 某个对象所属的类 是否能通过某个访问权限访问

也就是 用来探测 该对象变量是否能够转型为 探测的类型

通过的类型

自己

所有父类

继承链上所有声明实现的接口

接口强制类型转换

1 2 3
Animal animal = new Person();Calculator calculator = (Calculator)animal;calculator.calculate()

编译时写强制类型转换即可通过检查。

运行时会确认 所属对象是否能够提供接口。如果不能,会报错。

类型检测 x 类型转换

先检测 是否 安全

再转型 恢复权限

1 2 3 4
if (obj instanceof Inter) { Inter inter = (Inter)obj; inter.callFunctionViaInterface();}

项目进度跟进

简化 attack 代码

接口语法补充

实现多个接口

一个类可以声明实现多个接口

1
public class Person implements Calculator, Thinking

接口的方法可以重叠,没事。

类需要实现接口里所有的方法

扩展接口

一个接口可以扩展多个接口

1 2 3 4
public interface IA { void f0(); void f1();}
1 2 3 4
public interface IB { void f0(); void f2();}
1 2 3
public interface IC extends IA, IB { void f3();}

继承 和 接口 的对比

语法

extends / class

implements / interface

效果

继承后, 可以使用父类作为访问切面

继承同时, 还能代码重用

接口只用于定义一套新的访问权限

意图

继承主要用于子类扩展功能, 父类分享共性

接口主要用于定义新的访问切面

声明

继承父类, 父类可以有属性 和方法实现

实现接口, 接口只能有方法声明

方法覆盖

继承父类后, 可以选择覆盖父类方法 或者不覆盖

实现接口后, 必须确保实现接口内的方法

数量

一个类只能继承一个类, 多继承会带来调用问题

一个类可以实现多个接口

意义

继承的关系是 是

接口的关系是 能

总结

根本就是两个东西

抽象Abstract

一个修饰符,可以修饰类和方法

一旦修饰,变为虚无

抽象类abstract class

无法被 new

现象
1 2 3
public abstract class Cla { }
1 2 3!4 5
public class Dla { public void func() { new Cla(); }}
心态

有时一个类型太抽象, 仅仅为了消除代码冗余而出现

实际业务中, 并不会出现这个类型的对象

随堂检测
1.

接口是抽象的

A

B

不对

抽象方法Abstract 函数

没有实现代码,只有声明

现象
1 2 3
public abstract class Cla { public abstract void func();}
心态

有时方法无法实现

有时方法会被所有子类覆盖掉, 并且所有子类都不调用 super, 实现了也没意义

abstract 相关规则

abstract 方法 和 abstract 类

一个结构里,如果有抽象的方法(严格来讲是,没有实现代码的方法),那么这个结构 必须是 abstract

abstract 和 接口

接口里的所有的方法都是抽象的,你写不写 abstract 都视为写了 abstract

接口 abstract 方法 与 实现类

实现类 欢乐 2 选 1

实现所有方法

没有实现所有方法,类声明为 abstract

父类 abstract 方法 与 子类

子类 欢乐 2 选 1

实现所有抽象方法

没有实现抽象方法,类继续声明为 abstract

抽象 与 接口 的对比

本质区别

接口是接口,为了创建新的访问权限

抽象类,还是类,只是不能被new

资源

抽象类里,可能有属性、方法、抽象方法

接口里,只能有抽象方法

关系

类 是

接口 能

特殊情况

如果一个抽象类 里 都是抽象方法,

那么会跟接口还蛮像的。

但子类只能有一个父类,可以实现多个接口

final 修饰符

一旦修饰,不可改变

final 修饰变量

不可被二次赋值

final 修饰局部变量

第一次赋值后,不可被二次赋值

1 2!
final int a = 3;a = 4;
final 修饰参数变量

接收参数后,函数内不可被二次赋值

1 2 3 4 5 6 7!8
public void run() { f(3); f(5);} public int f(final int a) { a = 4;}
final 修饰属性

可以在声明、或所有构造方法里赋值

赋值后,不可被二次赋值

1 2 3 4!5 6
public class Cla { private final int a = 1; public void func() { a = 3; }}
1 2 3 4 5 6 7!8 9
public class Cla { private final int a; public Cla () { a = 2; } public void func() { a = 3; }}

final 修饰方法

方法不能被覆盖

从而阻止多态导致的行为改变

1 2 3 4 5
public class Cla { public final void func() { }}
1 2!3 4 5
public class Dla extends Cla { public void func() { }}
随堂检测
1.

接口里的方法 可以标记为 final

A

B

不对

final 修饰类

类不能被继承

1 2 3
public final class Cla { }
1!2 3
public class Dla extends Cla { }
随堂检测
1.

Object class 是 final 的

A

B

不对

2.

接口 可以标记为 final

A

B

不对

ZZAX 微信公众

文档一更新,立刻告诉你