- 今日内容
- 01. 接口概述与生活举例
- 02. 接口的定义基本格式
- 03. 接口的抽象方法定义
- 04. 接口的抽象方法使用
- 05. 接口的默认方法定义
- 06. 接口的默认方法使用
- 07. 接口的静态方法定义
- 08. 接口的静态方法使用
- 09. 接口的私有方法定义
- 10. 接口的私有方法使用
- 11. 接口的常量定义和使用
- 12. 接口的内容小结
- 13. 继承父类并实现多个接口
- 14. 接口之间的多继承
- 15. 多态的概述
- 16. 多态的格式与使用
- 17. 多态中成员变量的使用特点
- 18. 多态中成员方法的使用特点
- 19. 使用多态的好处
- 20. 对象的向上转型
- 21. 对象的向下转型
- 22. 用instanceof关键字进行类型判断
- 23. 笔记本USB接口案例_分析
- 24. 笔记本USB接口案例_实现
今日内容
- 接口
- 多态
01. 接口概述与生活举例
- 结合例子, 接口是什么思想?
总结: 接口就是一种公共的规范标准接口是对外暴露的一种规则定义接口的人:声明规则的使用接口的人:根据规则完成功能的人
02. 接口的定义基本格式
- 接口的基本定义格式
格式: interface 接口名{}
- 接口有会产生字节码文件吗?
总结: 会的
- 接口中可以定义的内容有?
- 接口在jdk1.7的特点:
只能定义常量抽象方法
- 接口在jdk1.8的特点:
默认方法静态方法
- 接口在jdk1.9的特点:
私有方法总结:1. 常量 --> 自定义常量 -> final2. 抽象方法 -> 必掌握3. 默认方法 -> 了解4. 静态方法 -> 了解5. 私有方法 -> 了解
03. 接口的抽象方法定义
- 接口中定义抽象方法的特点:
总结:定义的方法即使写成 void show(); 系统也会默认加上2个关键字 public abstract细节:abstract关键字不能和哪些关键字共存1. private-> 因为被abstract修饰的方法强制要求子类重写, 而被private修饰的方法子类重写不了, 二者冲突2. static-> 如果允许被static修饰, 就可以通过类名点去调用没有方法体的抽象方法, 这样做没有意义.3. final-> 变量 方法 类变量 : 就变成了常量, 只能被赋值一次方法 : 不能被重写类 : 不能被继承-> 因为被abstract修饰的方法强制要求子类重写, 而被final修饰的方法, 子类不能重写, 二者冲突.
04. 接口的抽象方法使用
- 思路: 接口不能实例化, 必须由实现类(子类的一种)去实现接口
- 实现接口的格式为:
总结:class 实现类类名 implements 接口名{}建议:作为接口的实现类(子类), 要么重写所有的抽象方法 --> 推荐方案要么将自己也变成一个抽象类 -> 不推荐步骤:1. 定义接口 interface 接口名 { .... }2. 找一个实现类实现这个接口-> implements class 实现类名 implements 接口名 { ... }3. 创建实现类对象, 并调用方法思路:抽象类 -> 共性的内容接口 -> 扩展的规则
05. 接口的默认方法定义
- jdk8开始, 才可以定义默认方法
- 定义默认方法的时候, 需要加入关键字default
格式:public default 返回值类型 方法名(){}
- 加入默认方法, 可以解决什么样的问题?
结论: 可以解决接口的升级问题interface A {public abstract void methodA();// 这里如果是一个抽象方法的话, 会影响到很多的实现类.public default void show(){System.out.println("我是新增加的功能show");}}class AImp1 implements A {@Overridepublic void methodA() {System.out.println("AImp1....");}}class AImp2 implements A{@Overridepublic void methodA() {System.out.println("AImp2....");}}
06. 接口的默认方法使用
- 调用方式是?
- 实现类是否可以对默认方法进行重写?
总结:1. 可以直接创建 实现类 的对象进行调用2. 可以如果实现类重写了, 那么调用的时候, 使用的就是重写之后的逻辑如果没有重写, 使用的就是接口当中默认的逻辑
eg.public interface Animal {<br /> public default void method (){<br /> System.out.println("默认方法");<br /> }<br /> }public Dog implements Animal {<br /> [@Override ]()<br /> public void method (){ //注意重写默认方法的时候, 不能写"default"关键字.按照普通的成员方法写就行了.<br /> System.out.println("重写的默认方法");<br /> }<br /> }
概念: 接口是一个干爹, 干爹中的数据, 实现类也是可以继承使用的.
07. 接口的静态方法定义
- jdk1.8开始, 可以开始定义静态方法
- 格式为?
总结:public static 返回值类型 方法名(参数列表){方法体;}
08. 接口的静态方法使用
- 调用方式是?
总结:1. 接口名称.静态方法名称();[ 注意事项 ]静态方法无法通过实现类名或者是实现类对象进行调用.只能通过接口名.静态方法名进行调用.interface Inter{public static void method(){System.out.println("1");}}interface Inter2{public static void method(){System.out.println("2");}}
class InterImp implements Inter,Inter2{}
InterImp ii = new InterImp();ii.method(); // 错误写法
main(){<br /> Inter.method(); // 接口名称.静态方法名称();<br /> }问题: 为什么接口中的静态方法, 不允许对象名调用.特点: 接口和类之间是实现关系, 可以单实现, 也可以多实现
既然可以多实现, 就有可能, 多个接口中定义了相同的静态方法, 但是方法体不一样.这时候就会出现冲突问题.所以, 接口中的静态方法. 只允许接口名.进行调用, 不允许对象名调用!
09. 接口的私有方法定义
- jdk1.9开始, 接口可以定义私有方法
- 什么情况下需要将接口中的方法进行私有?
总结:如果一个接口中有多个默认方法,并且方法中有重复的内容,那么可以抽取出来,封装到私有方法中,供默认方法 去调用。从设计的角度讲,私有的方法是对默认方法和静态方法的辅助换句话说:当发现接口中的多个默认方法中, 出现了重复的代码, 我们可以将这段代码抽取到一个方法当中.但又不希望实现类将整个逻辑性不强的方法继承使用, 就可以将该方法进行私有.举例:public interface MyInterfacePrivateA {public default void methodDefault1() {System.out.println("默认方法1");methodCommon();}public default void methodDefault2() {System.out.println("默认方法2");methodCommon();}private void methodCommon() {System.out.println("AAA");System.out.println("BBB");System.out.println("CCC");}}
10. 接口的私有方法使用
- 代码分析
结论 : 接口中定义的私有方法, 就是解决(普通/静态)方法中, 重复代码的问题.
11. 接口的常量定义和使用
- 接口中的变量只能是常量
总结: 因为默认加入了三个关键字 : public static finalint num = 10;
- fianl修饰变量
>* 基本数据类型其值不能发生改变final int a = 10;a = 20; // 错误.>* 引用数据类型地址值不能发生改变, 但是可以通过setXxx方法修改属性值.final Person p = new Person("张三",23);p.setAge(24); // 正确p = new Person("李四",24); // 错误
- 注意事项:
1. 接口中的常量, 必须给出初始化值.-> final修饰的变量, 如果是成员变量的话, 初始化时机.
解释:因为final修饰成员变量的初始化时机一共分为两种<br /> 1. 在创建成员变量的之后, 就直接赋值 --> 推荐方案<br /> 2. 在构造方法弹栈之前完成赋值注意的是, 接口中没有构造方法, 所以能够选择的初始化时机, 就只能是在创建成员变量的时候, 直接赋值.
- 江湖规矩
定义标识符的时候, 需要见名知意, 驼峰命名1. 变量 : 如果是一个单词, 所有字母小写 : age如果是多个单词, 从第二个单词的首字母开始大写 : maxAge2. 常量 : 如果是一个单词, 所有字母大写 : VALUE如果是多个单词, 所有字母大写, 但是单词之间需要以下划线隔开 : MAX_VALUE3. 类名 : 如果是一个单词, 首字母大写 Demo如果是多个单词, 每个单词的首字母大写 TestFinal4. 方法名: 如果是一个单词, 所有字母小写 : method()如果是多个单词, 从第二个单词的首字母开始大写 : getAge();5. 包名 : 一般都是公司的域名倒着写itheima.comcom.itheima.xx
12. 接口的内容小结
- 在Java 9+版本中,接口的内容可以有:
- 成员变量其实是常量,格式:
[public] [static] [final] 数据类型 常量名称 = 数据值;注意:常量必须进行赋值,而且一旦赋值不能改变。常量名称完全大写,用下划线进行分隔。
- 接口中最重要的就是抽象方法,格式:
[public] [abstract] 返回值类型 方法名称(参数列表);注意:实现类必须覆盖重写接口所有的抽象方法,除非实现类是抽象类。
- 从Java 8开始,接口里允许定义默认方法,格式:
[public] default 返回值类型 方法名称(参数列表) { 方法体 }注意:默认方法也可以被覆盖重写
- 从Java 8开始,接口里允许定义静态方法,格式:
[public] static 返回值类型 方法名称(参数列表) { 方法体 }注意:静态方法不能通过实现类的类名或者实现类的对象进行调用, 只能通过接口名.静态方法名进行调用.
- 从Java 9开始,接口里允许定义私有方法,格式:
普通私有方法:private 返回值类型 方法名称(参数列表) { 方法体 }静态私有方法:private static 返回值类型 方法名称(参数列表) { 方法体 }
- 接口的思想(重要)
总结:对比抽象类的思想抽象类: 被继承体现的是一种is..a的关系, 抽象类中的行为都是共性的行为.接口 : 接口当中定义的都是一些扩展的规则(特性的行为), 体现的是一种like..a的关系.
13. 继承父类并实现多个接口
- 注意事项:
总结:1.子接口重写默认方法时,default关键字可以保留。子类重写默认方法时,default关键字不可以保留。 子父类中不能出现default关键字, 出现就是错误代码.2.接口中,无法定义成员变量,但是可以定义常量,其值不可以改变,默认使用public static final修饰。3.接口中,没有构造方法,不能创建对象。4.接口中,没有静态代码块。
- 接口的出现, 打破了java只支持单继承的局限性, 为什么?
总结: 因为接口和类之间是实现关系, 可以单实现,也可以多实现并且可以在继承了一个类的同时, 实现多个接口interface A{}interface B{}interface C{}class InterImp extends Object implements A,B,C{
}
- 接口的子类需要注意哪些?
总结:1. 实现一个接口, 要么重写所有的抽象方法, 要么该实现类自己本身也是一个抽象类.2. 如果实现类实现多个接口, 多个接口中存在重复的抽象方法, 实现类之重写一个即可3. 如果实现类所实现的多个接口中, 存在重复的默认方法, 必须对冲突的默认方法重写interface A{public default void method(){System.out.println("A");}}interface B{public default void method(){System.out.println(B);}}class InterImp implements A, B{@Overridepublic void method(){System.out.println("...");}}4. 如果实现类, 从父类中继承下来的方法, 和接口中默认的方法重名了.优先用父类的方法.
public class Test1_Extends {<br /> public static void main(String[] args) {<br /> Dog d = new Dog();<br /> d.eat();<br /> d.show();<br /> }<br /> }class Animal{<br /> public void eat(){<br /> System.out.println("动物吃饭");<br /> }public void show(){<br /> System.out.println("父类的show方法");<br /> }<br /> }
interface Inter{void eat();public default void show(){System.out.println("接口中的show方法");}}class Dog extends Animal implements Inter{// 虽然和接口的抽象eat冲突, 这里使用的是父类的eat方法public void eat(){System.out.println("动物吃饭");}// 父类的show方法和接口中默认的show方法冲突, 优先使用的是父类的show方法// d.show();}
14. 接口之间的多继承
- 类与类的关系:
- 继承关系, 只支持单继承, 不支持多继承, 但是可以多层继承
- 类与接口的关系:
- 实现关系, 可以单实现, 也可以多实现, 并且可以在继承了一个类的同时, 实现多个接口
- 接口与接口的关系:
- 继承, 可以单继承, 也可以多继承!
interface A{void showA();}interface B{void showB();}interface C extends A,B{void showC();}class InterImp implements C{//重写三个抽象方法, 因为C当中继承到了showA, showB();}* 单独注意:如果多个父接口当中, 出现了重复的默认方法, 那么子接口必须对方法进行覆盖重写, 而且不能省略default关键字 !!interface A{public defalut void show(){System.out.println("a");}}interface B{public defalut void show(){System.out.println("B");}}interface C extends A,B{@Overridepublic defalut void show(){ // defalut不能省略.System.out.println("C");}}
15. 多态的概述
- 什么是多态?
总结: 事物存在的多种形态class Animal{}class Dog extends Animal{}main(){Dog d = new Dog(); // 事物以狗的形态出现Animal a = new Dog(); // 事物以动物的形态出现}
16. 多态的格式与使用
- 多态的前提是?
总结:1. 要有继承关系, 实现关系2. 要有父类引用指向子类对象. --> 多态的写法
17. 多态中成员变量的使用特点
- 多态中成员变量的使用特点?
总结:1. 编译看左边(父类), 运行看左边(父类)Fu f = new Zi();System.out.println(f.num); // 父类当中num所记录的值细节:编译看左边(父类), 运行看左边(父类)因为当前是父类引用指向子类对象, 父类的引用带有局限性, 只能看到堆内存当中super的一小块区域所以可以拿到的只能是super区域当中, 父类记录的数值.问题: 静态成员变量呢?静态修饰的成员跟类相关, 跟对象没有关系.Animal a = new Dog();System.out.println(a.abc);此处虽然是对象名.abc, 但在编译的时候也会翻译成类名.abcAnimal.abc --> 调用静态成员, 类名是谁的, 调用的就是谁的数值.
18. 多态中成员方法的使用特点
- 多态中成员方法的访问提点?
总结:1. 编译看左边(父类), 运行看右边(子类)动态绑定机制:动态绑定:在多态创建对象并调用成员方法的时候, 编译时会检测父类当中是否有此方法的声明有 : 编译通过, 但是运行的时候执行子类的方法没有 : 编译失败..
19. 使用多态的好处
- 无论右边new的是那个子类对象, 左边都不会发生变化
总结:1.Animal a = new Dog();Animal a = new Cat();...结论:多态的出现, 提高了代码的复用性, 因为有继承保证提高了代码的扩展性 --> 必掌握问题: 怎么就提高了?可以将方法的形参定义为父类类型, 该方法就可以接受这个父类的任意子类对象了.注意: 将方法形参定义为父类类型之后, 该方法可以接受这个父类的任意子类对象, 在方法内部一般都是调用的共性内容如果想要调用特性内容, 就需要向下转型, 莫不如直接创建子类对象.
20. 对象的向上转型
- 什么是多态的向上转型?
总结:1. Animal a = new Dog(); // 父类引用指向子类对象对比:double d = 10;
21. 对象的向下转型
- 为什么要向下转型?
总结:多态的弊端: 不能调用子类特有的属性和行为.如果非要调用子类特有的功能, 就必须向下转型.向下转型的举例:超人的例子.
注意: 向下转型的强转必须发生在子父类的关系内, 而且必须是转上去, 才能转下来.什么情况下需要用到向下转型?<br /> 答: 为了调用子类特有的属性和行为.ClassCastException(类型转换异常): 引用数据类型的强转, 出现了错误.
例如:
1. Animal a = new Cat();Dog d = (Dog)a; --> Cat和Dog之间没有子父类关系, 不能强转2. Animal a = new Animal();Dog d = (Dog) a; --> 必须要先进行向上转型, 才可以将数据正常的转型下来.
22. 用instanceof关键字进行类型判断
- instanceof关键字的作用是什么?
总结:1. 判断左边的引用, 是否是右边的数据类型.
public static void useAnimal(Animal a){ // Animal a = new Cat();<br /> a.eat();if(a instanceof Dog){<br /> Dog d = (Dog) a;<br /> d.lookHome();<br /> }else if (a instanceof Cat){<br /> Cat c = (Cat) a;<br /> c.catchMouse();<br /> }<br /> }
多态的好处:多态可以提高代码的扩展性, 可以将方法的形参定义为父类类型, 该方法就能接收这个父类的任意子类对象.方法内部一般只调用该体系当中共性的内容, 如果要调用特性的, 干脆就创建子类对象.
23. 笔记本USB接口案例_分析
- 看图说话
24. 笔记本USB接口案例_实现
- 示例代码
总结:1.
