Day Eight
- 昨日补充:常见的final类:
String Math
String不可变的: CharSequence - 字符序列 - 字符数组
底层实现: 字符数组 —> 字节数组 byte[] value
final value = 其他值
String str = “hello”;
str = “hi”;
多态
-
接口作为方法参数, 接口作为返回值:
具体使用的都是接口的实现类对象 -
多态的前提:
class MyInterfaceAImpl extends Object implmenets MyInterfaceA MyInterfaceA a = new MyInterfaceAImpl() -> 向上造型 Object o = new MyInterfaceAImpl() -> 向上造型 Fu fu = new Zi(); Animal a = new Cat();
父类型引用 指向 子类型对象 —> 向上造型
父类型 a = new 子类型对象(); 接口类型 a = new 实现类对象();
编译器 看 = 左边类型, 运行时JVM 看 = 右边类型
左边类型决定了可以调用哪些变量和能够调用哪些方法,
右边类型决定了最终使用的方法是哪个 - 优先调用自己重写过的
变量为父类变量,方法为子类继承(即调用父类的方法)和重写的方法(子类自己新增的方法和成员变量无法被调用)口诀: 编译看左边, 运行看右边
-
提前得知, 引用的 是什么类型的对象
Animal —> abstract void eat()
Cat —> void catchMouse() {}
Dog —> void watchHouse() {}多态:
Animal a1 = new Cat(); Animal a2 = new Dog();
-
未提前得知 引用的 是什么类型的对象(容易出现异常)
ClassCastException: 类型转换异常 -
解决方案:
转换之前先判断引用 实际上是不是要转换的类型对象
引用a instanceof 子类型 => 返回值类型:boolean
判断 a 是不是子类型对象
-
内部类: 在类中写的类
例如:
人体类 中写了一个 心脏类
车类 中写了一个 发动机类
- 种类:成员内部类,静态内部类,局部内部类 [ 匿名内部类 ]
-
成员内部类: 访问权限修饰: public,protected,(default),private
语法:public class Outer{ // ... public class Inner{ //.... } }
-
使用:
内部类中:可以随意使用外部类成员,包括私有成员
外部类中:使用内部类成员时需要创建内部类的对象
创建内部类对象格式:外部类名.内部类名 对象名 = new 外部类型().new 内部类型();
无关类中: 使用内部类成员
-
间接调用,在外部类方法中调用内部类方法
main方法中,调用外部类方法 -
直接调用,需要创建内部类对象
外部类.内部类 a = new 外部类().new 内部类();
内部类和外部类有同名成员变量
外部类的成员变量: 外部类.this.变量
内部类的成员变量: this.变量class Car { //外部类 class Engine { //内部类 } }
定义类:
public class Person { private boolean live = true; class Heart { public void jump() { // 直接访问外部类成员 if (live) { System.out.println("⼼脏在跳动"); } else { System.out.println("⼼脏不跳了"); } } } public boolean isLive() { return live; } public void setLive(boolean live) { this.live = live; } }
测试类:
public class InnerDemo { public static void main(String[] args) { // 创建外部类对象 Person p = new Person(); // 创建内部类对象 Heart heart = p.new Heart(); // 调⽤内部类⽅法 heart.jump(); // 调⽤外部类⽅法 p.setLive(false); // 调⽤内部类⽅法 heart.jump(); } } 输出结果: ⼼脏在跳动 ⼼脏不跳了
-
-
局部内部类:
在方法内部定义类, 只在方法中有效
在局部内部类中, 使用局部变量, 必须是final修饰的
JDK8 后,局部变量事实上没有发生改变,那么final可以省略特点:
一次性的类, 只能用一次
不能使用权限修饰符局部内部类, 需要类只使用一次,优化后 —> 匿名内部类
-
匿名内部类: 继承抽象类或实现接口
语法:new 接口/抽象类() { int a; ... // 实现的所有抽象方法 }
匿名内部类只能用一次new一个对象
匿名对象,只能使用一次,只能调用一次方法
注意: 匿名内部类 和 匿名对象 不是一回事 ! ! ! -
静态内部类 对比于 成员内部类 => 静态方法 对比于 成员方法
前两者两种类型之间的区别和后两者方法之间的区别相似,可以推断出来。(例如:静态内部类中不能调用成员变量,就像静态方法中不能调用成员方法。)
-