java 多态学习笔记
因为在想去一个家乡的小国企,每个月五六千块钱或许也不错,所以懈怠了学习。但是论语中有说:取乎其上,得乎其中;取乎其中,得乎其下;取乎其下,则无所得矣。如果我想着只是进一个小地方的国企,那么最后可能连找到工作都很悬。意识到错误,所以又来加紧学习的步伐了。
而且我相信论语中的这些话是对的。因为我读研初期,想着发sci一区的文章,所以很努力的学习,虽然现在因为导师的培养方针和实验室的规划影响,我已经是“只要能毕业就行了”,但是最开始的学习,让我不用担心自己一点成果也没有而无法毕业。但如果一开始我就抱持着“只要能毕业就行了”这种想法,可能现在就真的很担心是否能毕业了。(当然也有可能老师觉得我没有潜力直接给我一篇专利让我毕业……)
多态
封装、继承、多态。
对象代表什么,就得封装对应的数据,并提供数据对应的行为。将零散的内容归纳为一个整体。没有封装就没有继承和多态。
继承解决了程序内容冗余的问题。
多态可以将子类类型赋值给父类。多态是同类型的对象,表现出的不同形态。
// Person是Student的父类
Person p = new Student();
多态应用场景
同一个应用系统的注册,不需要多套底层逻辑!
可以通过各类对象共同的父类作为传入对象来构建方法。并可以调用各类中各自的成员方法。
多态的表现形式与应用前提
父类类型 对象名称 = 子类对象;
-
使用多态要求有继承/实现关系。
-
有父类引用指向子类对象("指向"就是“=”)
-
需要有方法重写
多态调用成员的特点
调用成员变量
public class Test {
public static void main(String[] args) {
Animal a = new Dog();
sout(a.name); // 会打印出"动物",编译或运行时会查看父类中是否有name变量,如果父类中没有,无论是编译or运行都是父类中的。
sout(a.show());// 会打印“dog show”,编译时会查看父类中是否有show()方法,但在运行时,会运行重写的子类中的方法。
}
}
父类Animal
class Animal{
String name = "动物";
public void show() {
sout("animal show.");
}
}
子类Dog
class Dog{
String name = "狗";
public void show() {
sout("Dog show.");
}
public void eat() {
sout("吃骨头");
}
}
多态的优势和缺点
多态的优势
- 在多态形式下,右边对象可以实现解耦合,便于扩展和维护。
Person p = new Student();
p.work();//工作交由学生进行
但倘若工作计划发生变更,工作交由教师进行:
Person p = new Teacher();
p.work();//只需在右侧更改对象类为teacher即可,即:业务逻辑发生改变时,后续代码无需修改
- 定义方法时,使用父类作为参数,可以接受所有子类对象,体现多态的扩展性与遍历
比如:ArrayList<> 倘若没有定义存储变量的类型,其add方法中可以直接add "object",而object是顶级父类,也就是可以添加所有类型的数据。
多态的缺陷
不能调用子类的特有功能:子类中新创建的方法,不能直接在创建的多态的对象上调用新方法。因为在编译的时候会检查父类中是否有相同名称的方法,但子类中新创建的方法在父类中显然是不存在的,所以不能直接调用。
- 解决办法
把调用者重新变回子类类型就可以了。
Animal a = new Dog();
a.eat(); //会报错,因为父类中没有eat()方法,如果需要调用子类中的方法,需要强制转换
Dog d = (Dog)a;
d.eat();
倘若我是一颗明珠,请为我擦去沾染的灰尘,再把我放在明亮的展台,让我放光彩!
可是您也从不是珠宝师,也没有珠宝盒。
我与您生而相同,只是我不愿同您一起,浮空飘零。
我是一粒愿沉于大地的灰尘,只想拜托您不要呼唤起风!
——《请让我平庸,妈妈!》