接口02
- 一、接口与继承类
- 1、引入
- 2、总结
- (1)接口和继承解决的问题不同。
- (2)接口比继承更加灵活。
- (3)接口在一定程度上实现代码解耦。
- 二、接口的多态性
- 1、多态参数
- ① 回顾:继承中的多态
- ② 接口的多态-案例1
- ③ 接口的多态-案例2
- 2、多态数组
- 3、多态传递
- 三、练习
- 四、类定义的进一步完善
一、接口与继承类
1、引入
接口&继承
猴子类有爬树天性,小猴子继承了猴子类之后,它可以自动获得这个爬树方法。鸟类会飞,小猴子想飞就需要实现这个方法。
class Monkey {
private String name;
public Monkey(String name) { this.name = name; }
public void climbing() { System.out.println("猴子会爬树"); }
public String getName() { return name; }
}
class LittleMon extends Monkey implements Fishable,Birdable{
public LittleMon(String name) { super(name); }
@Override
public void swimming() {
System.out.println("猴子:"+getName()+"通过学习,可以像鱼一样游泳");
}
@Override
public void flying() {
System.out.println("猴子:"+getName()+"通过学习,可以像鸟一样飞翔");
}
}
interface Fishable { void swimming(); }
interface Birdable { void flying();}
当子类继承了父类,就自动的拥有父类的功能。
如果子类需要扩展功能,可以通过实现接口的方式扩展。
可以理解实现接口是对java单继承机制的一种补充。
2、总结
(1)接口和继承解决的问题不同。
继承的价值主要在于:解决代码的复用性和可维护性。
接口的价值主要在于:设计,设计好各种规范(方法),让其它类去实现这些方法,更灵活。
(2)接口比继承更加灵活。
接口比继承更加灵活,继承是满足is - a的关系,
而接口只需满足 like - a 的关系。
(3)接口在一定程度上实现代码解耦。
[即接口规范性+动态绑定]
讲集合的时候会深入理解。
二、接口的多态性
1、多态参数
① 回顾:继承中的多态
父类类型的变量a可以指向继承AAA的子类的 对象实例。
class AAA {}
class BBB extends AAA {}
class CCC extends AAA {}
【main】
AAA a = new BBB();
a = new CCC();
② 接口的多态-案例1
接口 IF 类型的变量 if01 可以指向实现了IF接口的 类的对象实例。
public class InterfacePolyParameter {
public static void main(String[] args) {
IF if01 = new Monster();
if01 = new Car();
}
}
interface {}
class Monster implements IF {}
class Car implements IF {}
③ 接口的多态-案例2
在前面的Usb接口案例,Usblnterface usbinterface,既可以接收手机对象,又可以接收相机对象,就体现了接口多态(接口引用可以指向实现了接口的类的对象)。
前一篇文章中的 computer、usb、设备案例
work方法中:
① UsbInterface usbInterface形参是接口类型UsbInterface
② 实现了UsbInterface接口的类的对象实例,都可以传递参数
class Computer {
public void work(UsbInterface usbinterface) {
usbinterface.start();
usbinterface.stop();
}
}
public interface UsbInterface { //接口
public void start();//开始工作
public void stop();//停止工作
}
【main】
//创建手机,相机对象
Camera camera = newCamera();
Phone phone = new Phone();
//创建计算机
Computer computer = new Computer();
computer.work(camera);//把相机接入到计算机
computer.work(phone);//把手机接入到计算机
2、多态数组
回顾在学继承,多态数组定义为: 数组的定义类型为父类类型,里面保存的实际元素类型为子类类型。
见之前的文章
https://blog.csdn.net/yavlgloss/article/details/134521052?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522170115025416800182769750%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=170115025416800182769750&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-2-134521052-null-null.nonecase&utm_term=%E5%A4%9A%E6%80%81&spm=1018.2226.3001.4450
- 演示一个案例:
- 给Usb数组中,存放 Phone和相机对象,Phone类还有一个特有的方法call(),请遍历Usb数组,如果是Phone对象,除了调用Usb接口定义的方法外,还需要调用Phone特有方法call。
- InterfacePolyArr.java
public class InterfacePolyArr {
public static void main(String[] args) {
Usb[] usbs = new Usb[2];
usbs[0] = new Phone_();
usbs[1] = new Camera_();
for (int i = 0; i < usbs.length; i++) {
usbs[i].work();//动态绑定
//向下转型
if(usbs[i] instanceof Phone_) {//判断运行类型
((Phone_)usbs[i]).call();
}
}
}
}
interface Usb{
void work();
}
class Phone_ implements Usb{
public void call() {
System.out.println("打电话··");
}
@Override
public void work() {
System.out.println("手机工作中··");
}
}
class Camera_ implements Usb{
@Override
public void work() {
System.out.println("相机工作中··");
}
}
3、多态传递
接口存在多态传递现象。 InterfacePolyPass.java
interface IH {}
interface IG extends IH {}
class Teacher implements IG {}
IG ig = new Teacher();
IH ih = new Teacher();
如果IG继承了IH接口,而Teacher类实现了IG接口
那么,实际上就相当于 Teacher类也实现了IH接口
进一步理解这句话:
① hi一定是public ,一定可以被继承
② 此时在接口 IH 中添加了方法 hi(),IG 接口继承 IH,所以也继承了方法 hi。
③ Teacher类立马报错,要求实现 hi方法。
这就是所谓的接口多态传递现象。
三、练习
改错+分析输出
interface A{ int x = 0; }
class B{ int x = 1; }
class C extends B implements A {
public void pX() { System.out.println(x); }
public static void main(String[] args) { new C().pX(); }
}
我的答案:
接口中的 x 是 public static final 不可以更改,C同时拥有A的x和B的x 。。。不知道。。。
分析:
① interface A{ int x = 0; } 等价于 public static final int x = 0;
② class B{ int x = 1; } 这里的x是普通属性
③ public void pX() { System.out.println(x); }
这里的x指的是父类的x还是接口类的x呢? ==>会报错
【解决方法】:明确指定x
System.out.println(A.x); 访问接口中的静态x
System.out.println(super.x); 访问父类的x
四、类定义的进一步完善
类的五大成员(1)属性 (2)方法 (3)构造器 (4)代码块 (5)内部类
本笔记是对韩顺平老师的Java课程做出的梳理。方便本人和观看者进行复习。
课程请见: https://www.bilibili.com/video/BV1fh411y7R8/?spm_id_from=333.999.0.0&vd_source=ceab44fb5c1365a19cb488ab650bab03