1. 基础知识
多态:子类对象的多种父类形态;也就是把子类对象当做父类来使用,会丧失一些功能。
多态引用:子类对象赋值于父类类型的引用变量,父类类型的引用指向子类对象。例如Person P = new Chinese();多态引用中子类的特有成员/方法不可以访问
编译时类型(等号左边) 与 运行时类型(等号右边) 不一致,就出现了多态。
虚拟方法调用*****:当使用多态时,Person P = new Chinese();,多态引用P调用覆盖方法时,编译时会调用父类方法,而在运行时,会调用子类的重写方法。编译时编译器检查父类中是否有这个方法,编译通过后,在运行时会执行子类的重写方法。父类中的方法不执行,但又必须存在,所以称为虚拟方法,唯一作用是骗过编译器。
多态绑定:运行时运行谁的方法是不确定的,取决于右边所new出来的对象实体。
2. 代码测试
测试过程:创建父类Person,子类Chinese、American,BeiJing,其中Chinese、American继承Person类,BeiJing类继承Chinese类,并提供给三个类特有的属性和方法,最后在PersonTest类中完成多态的测试。
package com.hike.javase.polymophysm;
public class Person {
private String name;
private int age;
private String gender;
public Person() {
}
public Person(String name, int age, String gender) {
super();
this.name = name;
this.age = age;
this.gender = gender;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public String say() {
return "姓名:" + name + ",年龄" + age + ",性别:"+ gender;
}
public void sayHello() { //虚拟方法,不执行的方法,但必须存在
System.out.println("打个招呼");
}
}
package com.hike.javase.polymophysm;
/*
* 子类继承父类所有成员,不包括构造器
*/
public class Chinese extends Person{
private String shuXiang;
public Chinese() {
super();
}
public Chinese(String name, int age, String gender,String shuXiang) {
super(name, age, gender);
this.shuXiang = shuXiang;
}
public String getShuXiang() {
return shuXiang;
}
public void setShuXiang(String shuXiang) {
this.shuXiang = shuXiang;
}
@Override
public String say() {
return super.say() + ",属相:" + shuXiang;
}
@Override
public void sayHello() {
System.out.println("吃了吗?");
}
public void spring() {
System.out.println("中国人民过大年");
}
}
package com.hike.javase.polymophysm;
public class BeiJing extends Chinese{
public BeiJing() {
super();
}
public BeiJing(String name, int age, String gender, String shuXiang) {
super(name, age, gender, shuXiang);
}
@Override
public void sayHello() {
System.out.println("吃了吗您呐?");
}
}
package com.hike.javase.polymophysm;
public class American extends Person{
private boolean hasGun;
public American() {
super();
}
public American(String name, int age, String gender,boolean hasGun) {
super(name, age, gender);
this.hasGun = hasGun;
}
public boolean isHasGun() {
return hasGun;
}
public void setHasGun(boolean hasGun) {
this.hasGun = hasGun;
}
@Override
public String say() {
return super.say() + ",是否有枪:" + hasGun;
}
@Override
public void sayHello() {
System.out.println("How are you?");
}
public void christmas() {
System.out.println("merry christmas!");
}
}
package com.hike.javase.polymophysm;
public class PersonTest {
// 多态参数方法:参数是父类类型,可以接受其子类类型
public static void test(Person p) {
p.sayHello();
// 使用子类特有方法必须使用强转类型语句,强转有风险,强转前要判断
// 判断左侧的引用是否是右侧类型的实例,是返回true
// 是北京人一定是中国人,中国人不一定是北京人,所以要将范围最小的子类优先判断
if(p instanceof BeiJing){
((BeiJing)p).spring();
}else if(p instanceof Chinese) {
Chinese ch = (Chinese)p;
ch.spring();
}else if(p instanceof American) {
((American)p).christmas();//.的优先级最高,先完成强转,再调用特有方法
}else{
System.out.println("普通人类");
}
}
// 多态参数方法,提高兼容性
public static void main3(String[] args) {
Person p = new Person("王五",16,"男");
Person pCh = new Chinese("张三",20,"男","鼠");
Person pBj = new BeiJing("李四",15,"女","牛");
Person pAm = new American("lisa",32,"male",true);
test(p);
test(pCh);
test(pBj);
test(pAm);
}
// 多态的应用:多态数组
public static void main2(String[] args) {
// 创建一个数组,存储不同类型的对象,需要用到多态
Person[] arr = new Person[4];
arr[0] = new Person("王五",16,"男");
arr[1] = new Chinese("张三",20,"男","鼠");
arr[2] = new BeiJing("李四",15,"女","牛");
arr[3] = new American("lisa",32,"male",true);
System.out.println("##########1.say()方法与sayHello()方法的调用##########");
for(Person temp : arr) {
System.out.println(temp.say());
temp.sayHello();
}
System.out.println("##########2.按照年龄大小排序##########");
for(int i = 0; i < arr.length; i++) {
for(int j = 0; j < arr.length - i - 1; j++) {
if(arr[j].getAge() > arr[j + 1].getAge()) {
Person temp = arr[j];
arr[j] = arr[j + 1];
arr[j + 1] = temp;
}
}
}
for(Person temp : arr) {
System.out.println(temp.say());
}
System.out.println("##########3.按照年龄大小排序(选择排序)##########");
for(int i = 0; i < arr.length; i++) {
int minIndex = i;
for(int j = i + 1; j < arr.length; j++) {
if(arr[j].getAge() < arr[minIndex].getAge()) {
minIndex = j;
}
}
Person temp = arr[i];
arr[i] = arr[minIndex];
arr[minIndex] = temp;
}
for(Person temp : arr) {
System.out.println(temp.say());
}
}
// 多态基本使用方法
public static void main1(String[] args) {
Person p = new Person("王五",16,"男");
p.sayHello();
Person pCh = new Chinese("张三",20,"男","鼠");
// 通过多态引用调用虚拟方法
pCh.sayHello();
Person pBj = new BeiJing("李四",15,"女","牛");
pBj.sayHello();
Person pAm = new American("lisa",32,"male",true);
pAm.sayHello();
}
}