🎄接口之间的继承
接口可以继承一个接口, 达到复用的效果. 使用 extends
关键字
interface IRunning { void run(); } interface ISwimming { void swim(); } // 两栖的动物, 既能跑, 也能游 interface IAmphibious extends IRunning, ISwimming { } class Frog implements IAmphibious { ... }
通过接口继承 创建一个新的接口 IAmphibious 表示 “两栖的”. 此时实现接口创建的 Frog 类, 就要继续通过在Frog类中 重写实现 run 方法和 swim 方法.
接口间的继承相当于把多个接口合并在一起.
🎄Cloneable 接口和深浅拷贝
Java 中内置了一些很有用的接口, Clonable 就是其中之一.
Object 类中存在一个 clone 方法, 调用这个方法可以创建一个对象的 “拷贝”.
但是要想合法调用 clone 方法, 必须要先实现 Clonable 接口, 否则就会抛出CloneNotSupportedException 异常.
给Player类实现Clonable 接口
public class Player implements Cloneable{ protected String name; int []age=new int[1]; public Player(String name, int age) { this.name = name; this.age[0] = age; } @Override protected Object clone() throws CloneNotSupportedException { return super.clone(); } }
创建一个player1
对象,然后克隆一个player1
这里需要重点理解一下 深拷贝 和 浅拷贝,clone方法默认是 浅拷贝! 运行结果可以证明
public class 接口测试 { public static void main(String[] args)throws CloneNotSupportedException { Player player1 = new Player("kobe",18); Player player2 = (Player) player1.clone();//克隆player1 System.out.println("克隆player1"); System.out.println(player1); System.out.println(player2); System.out.println(); System.out.println("player1的名字和年龄:"+player1.name+player1.age[0]); System.out.println("player2的名字和年龄:"+player2.name+player2.age[0]); System.out.println("player1和player2的名字是否相同: " + (player2.name==player1.name)); System.out.println("player1和player2的年龄是否相同: " + (player2.age[0]==player1.age[0])); System.out.println(); System.out.println("将player2的名字改为 奥尼尔 年龄改为 20"); player2.name ="奥尼尔";//修改player2的名字 player2.age[0] =20;//修改player2的年龄 System.out.println("player1的名字和年龄:"+player1.name+player1.age[0]); System.out.println("player2的名字和年龄:"+player2.name+player2.age[0]); } }
运行结果如下
代码或许不太好理解,没关系,请看下图
然后将player2的 名字 年龄 都改一下
会发现一个问题,player2的age发生了修改,player1的age同时也会变,因为他们的age引用指向的是同一个地方
但是修改了名字,为什么player1的名字还是原来的kobe,而不是变成player2的奥尼尔,这是因为,字符串常量是不能被修改的,但是字符串的引用是可以修改的,所以会在字符串常量池中新创建一个字符串 “奥尼尔”,然后引用这个新的字符串
综上所述
什么是浅拷贝?
①我们这里说的浅拷贝是指我们拷贝出来的对象内部的引用类型变量和原来对象内部引用类型变量是同一引用(指向同一对象)。如上图所示
②但是我们拷贝出来的对象和新对象不是同一对象。
③简单来说,新(拷贝产生)、旧(原对象)对象不同,但是内部如果有引用类型的变量,新、旧对象引用的都是同一引用。
什么是深拷贝?
深拷贝:全部拷贝原对象的内容,包括内存的引用类型也进行拷贝
🎄总结
抽象类和接口都是 Java 中多态的常见使用方式. 都需要重点掌握. 同时又要认清两者的区别(重要!!! ).
核心区别: 抽象类中可以包含普通方法和普通字段, 这样的普通方法和字段可以被子类直接使用(不必重写), 而接口中不能包含普通方法, 子类必须重写所有的抽象方法.