java学习笔记—— 多态
Posted 玛丽莲茼蒿
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java学习笔记—— 多态相关的知识,希望对你有一定的参考价值。
一、 重写
1. 通过下面的例子看重写
2. 不是所有的方法都可以重写,被下面这些关键词修饰的不能重写
- static方法(静态方法属于类不属于对象,所以下面例子中对象b去调用相当于类B自己调用,调用的是属于类B的静态方法)
- final 方法 (被final修饰的属于常量,常量怎么能修改呢?)
- private 方法 (子类无法集成父类的private方法,自然也无法重写)
3. 面试题总结
记忆:父类(动物类)制定规则,要求方法eat()是protected而不是private,这样这个方法可以通过对象访问。那我们继承(老虎类)的时候就不能 把eat方法缩小成private,这样就违背父类制定规则的意愿了。所以修饰符只能扩大不能缩小。异常反过来记
二、 多态
2.1 多态存在的条件
- 子类重写父类方法
- 父类引用指向子类对象
2.2 多态是方法的多态(重写是方法的重写),属性没有多态(属性不能重写)
2.3 为什么要用多态?
可以使程序更灵活,可以扩展。
Animal an;
an = new Cat();
an.cry();
an = new Dog();
an.cry();
动态编译:程序只有在执行的时候才知道对象的实际类型(等号右边的类型)
2.4 多态
首先给出总结(只需要记住总结就行了):
对象能调用哪些方法,主要看等号左边引用的类型;如果调用的方法被子类重写过了,那么执行子类的方法。
1)父类、祖宗类的引用都可以指向子类对象
2)子类重写了父类的方法,那么父类的引用(上转型对象)调用子类重写过的方法(这个前面在重写部分已经讲过了)。
3)对象能调用哪些方法,主要看等号左边引用的类型。
举两个例子
可以这样记,父类一般是用来定义规则的抽象类,子类重写的就是这些规则,使用多态的时候我们也只会用这些重写父类的方法而不会使用子类自己单独的方法。所以真正使用多态的时候不会出现per.eat()这种问:因为我们一旦想使用子类的eat方法,就不会用多态去实现,而是直接用子类对象去调用
Student stu = new Student();
stu.eat();
4)类型转换
上面例子中,把父类型per对象强制转换为子类型就可以调用子类的eat函数了
PS: 引用数据类型和基本数据类型的“强制类型转换”刚好相反。
- 对于基本数据类型,高转低需要强转,会损失精度,比如float转int会损失小数。
- 对于引用数据类型,子类转换为父类对象(上转型)会损失子类的部分属性和方法(丢掉了子类更详细的东西,可以理解成损失“精度”),但是不需要强转。反而上图这种父类转子类增加精度(“人是中国人”)的需要强转(下转需要强制类型转换)。
PS: 只有new的是子类对象才能强转(只有多态才能强转),如果Person per指向new出来的父类对象Person,没法实现强转(想一下就知道,子类有很多属性和方法Person没有,强转的话这些东西从哪里来?)。所以下面这样是不对的:
Person per = new Person();
Student stu = (Student) per;
另一种思路:new 的 Person类干嘛要再转成Student类去使用student类的方法,直接new个Student类不就得了。
2.5 对象上转型
“动物是老虎的父类,从人的思维方式上来看,说“老虎是动物”属于上溯思维方式,会失去老虎的一些属性和方法”
1)称对象per为上转型对象
Person per = new Student();
或者这样更好理解一些:
Person per;
Student stu = new Student();
per = stu;
此时成对象per为对象stu的上转型对象。
2)对象只能上转不能下转(下转需要强制类型转换),例如不能说“人是中国人”、“动物是老虎”
3)上转型有哪些特点前面都说过了,只不过说的时候还没介绍它是上转型
三、 instanceof运算符
记住一句话 —— “对象 instanceof 父类/父类的父类/祖先类 都为 true”
上面例子中,需要注意的是红色框框出来的。对象的实际类型由等号右边决定。所以stu、per、obj的实际类型都是Student,所以对于instanceof Studnet/Person/Object的结果都是true。
以上是关于java学习笔记—— 多态的主要内容,如果未能解决你的问题,请参考以下文章