Java从零开始学十六(多态)

时间:2023-03-09 02:29:09
Java从零开始学十六(多态)

一、什么是多态

多态性是指允许不同类的对象对同一消息作出响应.多态性包括参数化多态性和包含多态性.多态性语言具有灵活、抽象、行为共享、代码共享的优势,很好的解决了应用程序函数同名问题.
多态有两种表现形式:重载和覆盖
首先说重载(overload),是发生在同一类中.与什么父类子类、继承毫无关系.
标识一个函数除了函数名外,还有函数的参数(个数和类型).也就是说,一个类中可以有两个或更多的函数,叫同一个名字而他们的参数不同.
他们之间毫无关系,是不同的函数,只是可能他们的功能类似,所以才命名一样,增加可读性,仅此而已!
再说覆盖(override),是发生在子类中!也就是说必须有继承的情况下才有覆盖发生.
我们知道继承一个类,也就有了父类了全部方法,如果你感到哪个方法不爽,功能要变,那就把那个函数在子类中重新实现一遍.
这样再调用这个方法的时候,就是执行子类中的过程了.父类中的函数就被覆盖了.(当然,覆盖的时候函数名和参数要和父类中完全一样,不然你的方法对父类中的方法就不起任何作用,因为两者是两个函数,毫不关系)

二、简单实现

package com.pb.demo6;

public abstract class Pet {
private String name; //宠物名字
private String sex; //宠物性别
private int health; //宠物的健康值 //宠物看病的方法
abstract void toHospital(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public int getHealth() {
return health;
} public void setHealth(int health) {
this.health = health;
} }
package com.pb.demo6;
/*
* 小狗类
*/
public class Dog extends Pet { @Override
void toHospital() {
//小狗看病的方法
System.out.println("小狗看病:打针、吃药!"); } } package com.pb.demo6;
/*
* 小猪类
*/
public class Pig extends Pet { @Override
void toHospital() {
System.out.println("小猪看病:打针、睡觉!"); } }
package com.pb.demo6;
/*
* 小鸟类
*/
public class Bird extends Pet { @Override
void toHospital() {
//小鸟看病的方法
System.out.println("小鸟看病:吃药、休息!"); } }
package com.pb.demo6;
/*
* 宠物医生类
*/
public class Doctor { //医生治疗方法
public void cure(Pet pet){ //将宠物传参 if(pet.getHealth()<50){ //判断健康值小于50
//调用看病的方法
pet.toHospital();
//将健康值设置为60,健康
pet.setHealth(60);
}
} }

测试类

package com.pb.demo6;
/*
* 测试类
*/
public class Test { public static void main(String[] args) {
//声明医生对象
Doctor dc=new Doctor();
//声明宠物对象为小鸟
Pet brid=new Bird();
//调用医生的治疗方法
dc.cure(brid);
//声明宠物对象为小狗
Pet dog=new Dog();
//调用医生的治疗方法
dc.cure(dog);
//声明宠物对象为小猪
Pet pig=new Pig();
//调用医生的治疗方法
dc.cure(pig); } }

结果:

小鸟看病:吃药、休息!
小狗看病:打针、吃药!
小猪看病:打针、睡觉!

三、对象的多态性

 对象的多态性主要分为以下两种类型:
向上转型和向下转型

3.1 对象向上转型:

父类 父类对象 = 子类实例 ;
向上转型:子类对象 ->父类对象
对于向上转型,程序会自动完成,格式:
如上面的:
 //声明宠物对象为小鸟
Pet brid=new Bird();
//声明宠物对象为小狗
Pet dog=new Dog();
//声明宠物对象为小猪
Pet pig=new Pig();

编译时类型为:Pet,而运行时类型为具体的类型

也就是说编译时类型由声明该变量时使用类型决定,而运行时类型由实际赋给该变量的对象决定

3.2 对象向下转型:

向下转型:父类对象 ->子类对象
对于向下转型时,必须明确的指明要转型的子类类型,格式:
子类 子类对象 = (子类)父类实例 ;强制类型转换
 上面的例中,子类没有自己的方法,如果子类有自己的方法,医生类中还能调用吗?显然不能,因为是向上转为父类后,只能调用父类的方法,如果要调用子类的方法就需要用到向下转型要用到instannceof

四、instanceof 关键字

在java中可以使用instanceof关键字判断一个对象到底是那个类的实例
对象 instanceof 类   ->返回boolean类型
package com.pb.demo6;

public abstract class Pet {
private String name; //宠物名字
private String sex; //宠物性别
private int health; //宠物的健康值 //宠物看病的方法
abstract void toHospital(); public String getName() {
return name;
} public void setName(String name) {
this.name = name;
} public String getSex() {
return sex;
} public void setSex(String sex) {
this.sex = sex;
} public int getHealth() {
return health;
} public void setHealth(int health) {
this.health = health;
} }
package com.pb.demo6;
/*
* 小鸟类
*/
public class Bird extends Pet { @Override
void toHospital() {
//小鸟看病的方法
System.out.println("小鸟看病:吃药、休息!"); }
public void fly(){
System.out.println("小鸟会飞!");
} }
package com.pb.demo6;
/*
* 小狗类
*/
public class Dog extends Pet { @Override
void toHospital() {
//小狗看病的方法
System.out.println("小狗看病:打针、吃药!"); }
public void run(){
System.out.println("小狗在地上跑!");
} }
package com.pb.demo6;
/*
* 小猪类
*/
public class Pig extends Pet { @Override
void toHospital() {
System.out.println("小猪看病:打针、睡觉!"); }
public void sleep(){
System.out.println("小猪要睡觉!");
}
}
package com.pb.demo6;
/*
* 宠物医生类
*/
public class Doctor { //医生治疗方法
public void cure(Pet pet){ //将宠物传参 if(pet.getHealth()<50){ //判断健康值小于50
//调用看病的方法
pet.toHospital();
//将健康值设置为60,健康
pet.setHealth(60);
//判断是宠物类型
if(pet instanceof Dog){
//向下转型,强制类型转制
Dog dog=(Dog)pet;
//调用小狗自己的方法
dog.run();
}else if(pet instanceof Bird){
//向下转型,强制类型转制
Bird bird=(Bird)pet;
//调用小鸟自己的方法
bird.fly();
}else if(pet instanceof Pig){
//向下转型,强制类型转制
Pig pig=(Pig)pet;
//调用小猪自己的方法
pig.sleep();
}
}
} }
package com.pb.demo6;
/*
* 测试类
*/
public class Test { public static void main(String[] args) {
//声明医生对象
Doctor dc=new Doctor();
//声明宠物对象为小鸟
Pet brid=new Bird();
//调用医生的治疗方法
dc.cure(brid);
//声明宠物对象为小狗
Pet dog=new Dog();
//调用医生的治疗方法
dc.cure(dog);
//声明宠物对象为小猪
Pet pig=new Pig();
//调用医生的治疗方法
dc.cure(pig); } }

结果:

小鸟看病:吃药、休息!
小鸟会飞!
小狗看病:打针、吃药!
小狗在地上跑!
小猪看病:打针、睡觉!
小猪要睡觉!

五、父类做为形参

package com.pb.demo2;
/*
* 商品类
*/
public class Goods {
//打印商品价格方法
public void printPrice(){
System.out.println("打印商品价格");
}
} package com.pb.demo2;
/*
* 食品类
*/
public class Foods extends Goods { @Override
public void printPrice() {
System.out.println("打印食品类的商品价格!");
} }
package com.pb.demo2;
/*
* 电视类
*/
public class TVs extends Goods { @Override
public void printPrice() {
System.out.println("打印电视类商品价格!");
} }

测试类:

package com.pb.demo2;

public class Test {

    public static void main(String[] args) {
//声明3 个商品价格
Goods good=new Goods();
Foods food=new Foods();
TVs tvs=new TVs();
//调用方法
showPrice(good);
showPrice(food);
showPrice(tvs); }
//显示商品价格方法
static void showPrice(Goods good){
good.printPrice();
}
}

结果:

打印商品价格
打印食品类的商品价格!
打印电视类商品价格!