多态
定义:说白了其实就是不同环境下表现出来的多种形态
(正如一个人在家、公司、学校等地方扮演着不同的角色)
在Java中多态存在的三个条件:
- 继承
- 重写
- 向上转型【父类引用指向子类对象(或者说子类的对象赋给父类的变量)】
(向上转型,此过程为隐式转换,即是自动的,不需要强转。)
先以People为例:
编程逻辑:
- 父类People,爱好hobby()
- 子类Man和Woman重写hobby()方法
- 在Test中,分别创建子类的对象,调用hobby()方法。
People.java
public class People {
public void hobby() {
System.out.println("爱好");
}
}
Man.java
public class Man extends People {
public void hobby() {
System.out.println("抽烟喝酒烫头");
}
}
Woman.java
public class Woman extends People {
public void hobby() {
System.out.println("shopping");
}
}
public class Test {
public static void main(String[] args) {
Man zhangsanMan = new Man();
zhangsanMan.hobby();
Woman lisiWoman = new Woman();
lisiWoman.hobby();
// 子类的对象赋给父类的变量 向上转型
People people = new Man();
people.hobby(); // 等对多态熟悉后这两行可以写为下面的test(new Man())即可;
// Man wangwuMan = new Man();
Woman wangwuMan = new Woman();
// main是静态方法,java语法,静态方法只能调用静态方法。
test(wangwuMan);
// test(new Man());
// null是引用类型的默认值 String
}
public static void test(People people) {
System.out.println("test");
people.hobby();
}
}
Java中,空对象调方法,造成nullpointerexception(空指针异样)
总结:根据多态中向上转型的特性,即子类的对象转成父类的类型(隐式,自动转换的),所以,我们在定义方法,倘若遇到需要传递对象,则方法的参数会使用父类的类型,而不使用子类的类型。
里面的(People people )其实是(类型 属性)
类似于 int a
…
如此,将来倘若People扩展时,存在其他的子类,当需要调用上面的方法时,方法内部不需要做任何改变,只需要传递该子类的对象即可。
向上转移的分析
父类指向子类对象的原因:
(用实际代码进行对比)
向上转型前:
注:上面两个重载的方法由于方法体内容都一样,应该合并在一起,不要出现重复冗余的代码,所以就需要用到多态。
能够实现合并的核心是: 子类的对象能够赋给父类的变量(向上转型)。
向上转型后:
题外点:
数据类型:基本类型、引用类型(类、数组、接口)
图中标的数据类型也是参数类型,其实是一个意思。