多态
polymorphic
多态的概述,形式
-
同类型的对象执行同一个行为,会表现出不同的行为特征
-
多态的常见形式
-
父类类型 对象名称 = new 子类构造器
-
接口 对象名称 = new 实现类构造器
-
-
多态中成员访问特点
-
方法调用:编译看等号左边,编译的时候我们看的还是Animal里面有没有run()方法,执行看右边:执行的时候具体执行的是子类Dog里面的run方法
-
变量调用:编译看左边,运行看左边。变量没有多态这么一说,只有行为有多态
-
-
多态的前提
-
要有继承/实现关系,即要有子类父类的关系
-
父类引用指向子类对象:Animal d1=new Dog();
-
有方法重写
-
多态的好处
-
在多态形势下,右边对象可是实现解耦合,便于扩展和维护
-
换句话说就是给汽车换轮胎,旧轮胎不好同换成新轮胎,而不是自己造一个新轮胎
-
定义方法的时候,使用父类作为参数,该方法就可以接收这个父类的一切子类对象,体现出多态的扩展性与便利
缺点
-
多态下不能使用子类的独有功能
-
因为编译的时候看的是父类Animal的行为,但是如果子类Dog中有一个行为是父类Animal中没有的 此时Animal.子类独有行为就会报错。
缺点的解决方法
-
引用类型的自动类型转换:从子到父:子类对象赋值给父类类型变量:Animal a= new Dog()
-
强制类型转换:把父类对象赋值给子类变量:子类 对象变量=(子类)父类类型变量
-
父类类型的变量强转为子类类型的变量以后就可以调子类独有的方法了
注意
-
如果转型后的类型和对象的真是类型不是同一类型,那么运行时就会报错,但是编译时不会出错
-
换句话来说:就是可以把动物类型转为狗类,但是不能把狗类转为猫类
-
Animal t=new Cat();
-
Dog d=(Dog) t;//这样就会报错,因为他把猫类型强转为类狗类型
-
所以强制类型转换前使用instanseof判断一下
-
if (d instanceof Dog){//判断d的真是类型是不是狗 Dog d3=(Dog)d;//如果是狗,就强转为狗 d3.lookDoor(); }else if(d instanceof Cat) { Cat c=(Cat)d;//如果是猫就强转为猫 c.miaomiao(); }
内部类
概述
-
定义在一个类里面的类
-
作用:当一个事物的内部还有一部分需要一个完整的结构进行表述,而这个内部的完整结构又只为外部事物提供服务,那么这个内部的完整结构就可以选择使用内部类来设计
-
内部类提供了更好的封装性,内部类本身就可以用private protected等修饰,封装性可以做更多的控制
分类
-
静态内部类(了解)
-
有static修饰属于外部类本身
-
和普通的类完全一样,类有的成分他都有,只是在别人里面而已
-
外部类名.内部类名 对象名=new 外部类名.内部类构造器;
-
静态内部类中可以直接访问外部类的静态成员
-
需要在静态内部类中创建外部类的对象才可以访问外部类的实例成员
-
-
成员内部类(了解)
-
无static修饰,属于外部类的对象:public class Inner{}
-
jdk16之前,成员内部类中不能定义静态成员,jdk16开始也可以定义静态成员了
-
外部类名.内部类名 对象名=new 外部类构造器。new 内部类构造器();
-
因为成员内部类属于外部类的对象,要先把外部类的对象创建出来以后才能创建内部类的对象
-
-
内部类中访问外部类与内部类重名的变量:外部类名.this.变量名
-
-
匿名内部类(重点)
-
本质上是一个没有名字的局部内部类,定义在方法中,代码块中
-
作用:方便创建子类对象,最终目的是为了简化代码编写
-
匿名内部类写出来就会产生一个对象 a
-
但是这个对象绝对不是抽象类Animal的对象
-
可以理解为是抽象类的子类tiger的对象
-
匿名内部类可以作为方法的实际参数进行传输
-
使用场景
-
给按钮绑定点击事件
-
-