多态&&内部类&&匿名内部类&&Lambda表达式
多态 【掌握】
什么是多态
是一个事物表现出来的多种形态
猫/狗 也可以说是动物
摩托车 也可以说是机动车
学生 也可以说成是人
面试题:以下诗词体现的是面向对象的哪种特征
苏轼曰:横看成岭侧成峰,远近高低各不同
体现了多态的特征
在Java中的多态,是一个对象表现出来的多种形态
// 狗是狗
Dog d = new Dog();
// 狗是动物,体现了多态
Animal a = new Dog();
体现在:父类的引用指向子类的对象
父类类型的变量去记录子类对象的地址
多态的前提
1、有继承/实现关系
2、一般会有方法重写
3、父类的引用指向子类的对象
接口的引用指向实现类的对象
多态下的成员访问特点
成员变量
编译看左边(父类),运行看左边(父类)
成员方法
非静态的成员方法
编译看左边(父类),运行看右边(子类)
静态的成员方法
编译看左边(父类),运行看左边(父类)
总结:编译都看左边(父类),只有非静态的成员方法运行的时候看右边(子类),其余都看左边
多态的优缺点
优点:
提高程序扩展性
缺点:
无法使用子类特有成员
多态的类型转换
这里的类型转换指的是引用类型的转换,基础班学习的类型转换是基本类型的转换
向上转型:类似于基本类型转换中的隐式转换/自动类型提升,子类类型转换为父类类型,父类引用指向子类对象就是向上转型
Animal a = new Dog();
向下转型:类似于基本类型转换中的强制转换,父类类型转换为子类类型
子类类型 变量名 = (子类类型)父类类型的值;
Dog d = (Dog)a;
向下转型中的问题和解决
类型转换异常:ClassCastException
解决:先判断,是这种类型,再转换
判断:instanceof运算符
boolean flag = 对象(名) instanceof 类;
多态的应用场景
1、创建的对象时候
Animal a = new Cat();
private BaseStudentDao studentDao = StudentDaoFactory.getStudentDao();
2、方法参数传递
public static void useAnimal(Animal a){
}
useAnimal(new Dog());
useAnimal(new Cat());
3、方法的返回值
public static BaseStudentDao getStudentDao() {
return new StudentDao();
// return new OtherStudentDao();
}
方法的参数传递:方法要什么类型就传什么类型,要几个参数就传几个参数
参数是基本类型
参数是引用类型
数组
类:Student Dog Animal String
接口:Jump Inter BaseStudentDao List
如果形参是数组,就传递对应类型的数组对象即可
如果形参是类类型,就传递该类的对象,或者该类的子类对象
如果类是一个抽象类,则只能传递该类的子类对象,因为抽象类无法创建对象
如果形参是接口类型,则只能传递该接口的实现类对象,因为接口无法创建对象
内部类
成员内部类 【了解】
直接定义在类中方法外的类,在类的成员位置定义的
注:以后我们基本上不会编写和使用成员内部类,只要以后查看源码看到了能知道这是内部类即可
内部类的访问特点
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象
外界创建成员内部类格式
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
举例:Outer.Inner oi = new Outer().new Inner();
可以在类中直接定义的内容
成员变量
成员方法
构造方法
成员内部类(内部接口、内部枚举)
代码块(静态代码块、构造代码块)
局部内部类 【了解】
直接定义在方法中的类,在类的局部位置定义的
注:以后我们基本上不会编写、使用成员内部类,甚至见都见不到
匿名内部类 【掌握】
什么是匿名内部类
就是一个没有名字的局部内部类
作用
简化代码块,将类的继承/实现、方法重写、对象创建者三步一起完成
格式
new 类/接口名() {
// 方法的重写或者实现
};
类/接口类型 变量名 = new 类/接口名() {
// 方法的重写或者实现
};
匿名对象:没有名字的对象,没有变量引用的对象
new Student();
匿名内部类:没有名字的类
匿名内部类的匿名对象:创建的匿名内部类的对象没有使用一个变量来接收这个对象
原理
匿名内部类是在创建该类的子类对象,或者创建该接口的实现类对象
匿名内部类的使用场景
一切需要该类的子类对象,或者该接口的实现类对象的场景大部分都是可以使用匿名内部类的
1、调用方法当做实参
2、当做方法的返回值
3、直接多态的方式创建该类的子类对象,或者该接口的实现类对象
Lambda表达式
作用:简化代码,可以对部分匿名内部类的代码做进一步的简化
Lambda表达式的使用前提
1、必须是一个接口
2、这个接口中有且只有一个抽象方法
有且只有一个抽象方法的接口,称之为函数式接口(FunctionalInterface)
可以通过一个@FunctionalInterface注解来验证接口是否是函数式接口
Lambda表达式的原理:创建接口的实现类对象
Lambda表达式的格式
标准格式
() -> {}
():指的是接口的抽象方法的形式参数
->:传递的意思,固定的格式
{}:实现了抽象方法之后的方法体内容
省略格式
() -> {}
规则:
():
0个参数:小括号不能省略
1个参数:小括号和数据类型可以省(如果要省略小括号,则一定要省略数据类型)
2个及其以上参数:只能省略数据类型,不能省略小括号
->:不能省略
{}:
只有一行语句的时候才可以省略,可以省略{}、return和语句结尾的分号,要省则三者同时省
如果一行以上的语句则不可以省略
本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 Ahir's Blog!
评论
GitalkDisqusjs