多态
多态: 一个父类(或接口)变量根据它所引用的对象(子类对象)的不同,而表现出不同的行为
多态的前提:
- 父子类关系(接口或实现类)
- 方法发生重写
- 父类变量引用(指向)子类的对象
多态的好处:
- 扩展性,通用性
- 只能通过父类来调用方法,父类中必须要有此方法(子类中重写了父类的方法),执行的是子类中重写后的方法
转型
代码表示:
父类 父类变量名 = new 子类1();//向上转型
子类1 子类变量名1 = (子类1)父类变量名;//向下转型,强制类型转换,就可以使用子类特有方法
//特别注意
子类2 子类变量名2 = (子类2)父类变量名;//不可以用子类1创建的父类对象向下转型为子类2
instanceof //instance本意是实例,对象 instanceof 就是判断该对象能否能转换为右侧的类型,它表达的是(是同一个)的关系
对象 instanceof 类型 返回 true 表示左边的对象可以被转换为右边类型, false 就表示不能转换
内部类
1.成员内部类
//内部类的使用
//1.更精准的表达抽象时的嵌套关系
//2.内部类可以访问外部类的私有成员,如果是平级关系的类则无法做到
//3.一般会在Person类内来创建并使用 Head 和 Body 这样的内部类
2.静态内部类
//使用static修饰的内部类(一般用于独立测试使用)
成员内部类与静态内部类的区别
//静态成员内部类不能访问外部类的非静态成员变量
//静态成员内部类可以访问外部类的静态成员变量
//成员内部类可以访问外部类的成员变量
//可以访问外部类的静态成员变量
3.局部内部类
//局部内部类中如果访问"外层方法的局部变量",此局部变量相当于是final,只能读,不能改
//同样适用于 匿名内部类
public void Test(){
int t = 10;
class Inner{
public void x(){
t = 20;//编译报错
}
}
}
4.匿名内部类
//配合抽象类和接口使用
接口 变量名 = new 接口(){
实现接口中的抽象方法
}
变量名.抽象方法()
Lambda
Lambda是:在某些场景下对匿名内部类做简化
Lambda表达式和匿名内部类的区别
所需类型不同
1.匿名内部类: 可以是接口,也可以是抽象类,还可以是具体类
2.Lambda表达式: 只能是接口
使用限制不同
1.如果接口中有且仅有一个抽象方法,可以使用Lambda表达式,也可以使用匿名内部类
2.如果接口中多于一个抽象方法,只能使用匿名内部类,而不能使用Lambda表达式
实现原理不同
1.匿名内部类: 编译之后,产生一个单独的.class字节码文件
2.Lambda表达式:编译之后,没有一个单独的.class字节码文件,对应的字节码会在运行的时候动态生成
//lambda 格式
()->{}
//只有一个参数可以省略()
//大括号中只有一行代码可以省略{};
函数式接口-只有一个抽象方法的接口
- Comparator—>比较器
- Consumer —>用户,消费者
- Function —>函数
- Predicate —>谓语,使…基于, 断言
- Supplier —>供应商