Java进阶总结——多态
1.多态
/**
* 多态
* 1.将子类的对象赋值给父类的引用
* 2.当用父类引用调用父类的方法时,执行的是子类重写的方法
* 3.如果使用方法 必须有继承关系
* */
package day10;
public class Cat extends Pet{
public Cat() {
// TODO 自动生成的构造函数存根
}
public Cat(int health) {
this.setHealth(health);
}
@Override
public void toHospital() {
// TODO 自动生成的方法存根
if (this.getHealth()<50) {
System.out.println("小猫看病,食补");
this.setHealth(90);
}
}
}
package day10;
public class Dog extends Pet{
//构造方法
public Dog() {
// TODO 自动生成的构造函数存根
}
public Dog(int health) {
this.setHealth(health);
}
//重写父类方法
@Override
public void toHospital() {
// TODO 自动生成的方法存根
if (this.getHealth()<60) {
System.out.println("给狗狗打针吃药");
//恢复健康值
this.setHealth(90);
}
}
}
package day10;
public class Penguin extends Pet{
//构造方法
public Penguin() {
// TODO 自动生成的构造函数存根
}
public Penguin(int health) {
this.setHealth(health);
}
@Override
public void toHospital() {
// TODO 自动生成的方法存根
if (this.getHealth()<50) {
System.out.println("给企鹅食疗");
this.setHealth(90);
}
}
}
package day10;
//父类
public class Pet {
//属性
private int health;
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
//方法
public void toHospital() {
System.out.println("去医院看病");
}
}
package day10;
public class Master {
/* //给狗看病
public void cure(Dog dog) {
dog.toHospital();
}
//给企鹅看病
public void cure(Penguin pen) {
pen.toHospital();
}
*/
//给所有宠物看病
public void cure(Pet p) {
//子类的对象,父类的引用
System.out.println("p=="+p);
//调用去医院方法
p.toHospital();
}
public static void main(String[] args) {
//初始化一个master对象
Master m=new Master();
//初始化dog对象,将dog对象赋值给宠物类型(父类
Dog dog=new Dog(40);
System.out.println(dog);
Pet p=dog;
System.out.println(p);
//给宠物看病
m.cure(p);
//同上
Penguin pen=new Penguin(20);
System.out.println(pen);
Pet p1=pen;//将子类的对象赋值给父类的引用
System.out.println(p1);
m.cure(p1);
//再加个小猫类;
Cat cat=new Cat();
System.out.println(cat);
Pet p2=cat;
System.out.println(p2);
m.cure(p2);
}
}
输出结果:
2.抽象类
/**
* 1.抽象类与一般类一样 可以拥有属性 方法 构造方法
* 2.抽象类不能直接实例化,只允许子类继承实例化
* 3.抽象类可以定义抽象方法,如果一个类中有抽象方法,那么该类必须是抽象类
* 抽象类在定义的时候必须使用abstract修饰
* */
package day10.Test;
public class Cat extends Pet{
public Cat() {
// TODO 自动生成的构造函数存根
}
public Cat(int health) {
this.setHealth(health);
}
@Override
public void toHospital() {
// TODO 自动生成的方法存根
if (this.getHealth()<50) {
System.out.println("小猫看病,食补");
this.setHealth(90);
}
}
}
package day10.Test;
public class Dog extends Pet{
//构造方法
public Dog() {
// TODO 自动生成的构造函数存根
}
public Dog(int health) {
this.setHealth(health);
}
//子类特有方法
public void playDisc() {
System.out.println("小狗会接飞盘");
}
//重写父类方法
@Override
public void toHospital() {
// TODO 自动生成的方法存根
if (this.getHealth()<60) {
System.out.println("给狗狗打针吃药");
//恢复健康值
this.setHealth(90);
}
}
}
package day10.Test;
public class Penguin extends Pet{
//构造方法
public Penguin() {
// TODO 自动生成的构造函数存根
}
public Penguin(int health) {
this.setHealth(health);
}
//子类特有行为
public void swimming() {
System.out.println("企鹅在南极游泳");
}
@Override
public void toHospital() {
// TODO 自动生成的方法存根
if (this.getHealth()<50) {
System.out.println("给企鹅食疗");
this.setHealth(90);
}
}
}
package day10.Test;
public class Monkey extends Pet{
@Override
public void toHospital() {
// TODO 自动生成的方法存根
//重写方法 必须在子类中重写
}
}
package day10.Test;
//父类
public abstract class Pet {
//属性
private int health;
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
/**
* 当前方法没有被子类调用 都对该方法进行了重写
* 可以使用抽象方法定义 重新定义方法
* 抽象方法的特点
* 1.必须使用abstract进行修饰
* 2.不能有方法体
* 3.不能使用private、final、static修饰符
* 4.子类必须重新该方法,如果子类也是抽象类,可以不用重写
* */
//方法
public abstract void toHospital() ;
}
package day10.Test;
public class Master {
//给所有宠物看病
public void cure(Pet p) {
//子类的对象,父类的引用
System.out.println("p=="+p);
//调用去医院方法
p.toHospital();
//如果子类想要执行自己的特性,需要进行强制类型转换
//instance 判断对象的类型,保证数据类型转换正确
//执行子类特有行为
//强制转换 父类转子类 下转上 需要使用强制转换符
if (p instanceof Dog) {
Dog dog=(Dog)p;
dog.playDisc();
}else if (p instanceof Penguin) {
Penguin p1=(Penguin)p;
p1.swimming();
}
}
public static void main(String[] args) {
//初始化一个master对象
Master m=new Master();
//初始化dog对象,将dog对象赋值给宠物类型(父类
Dog dog=new Dog(40);
System.out.println(dog);
Pet p=dog;//下转上
System.out.println(p);
//给宠物看病
m.cure(p);
//同上
Penguin pen=new Penguin(20);
System.out.println(pen);
Pet p1=pen;//将子类的对象赋值给父类的引用
System.out.println(p1);
m.cure(p1);
Cat cat=new Cat();
System.out.println(cat);
Pet p2=cat;
System.out.println(p2);
m.cure(p2);
//抽象类不能直接被实例化
//Pet p3=new Pet() ;
}
}
输出结果:
3.练习题
3.1第一题
宠物饿了,主人需要为宠物喂食,使用多态实现该过程
不同宠物吃的东西不一样
不同宠物吃完东西后恢复健康值不一样
健康值达到100时,不需要继续喂食
package day10.Test1;
//子类
public class Dog extends Pet{
@Override
public void eatFoods() {
// TODO 自动生成的方法存根
System.out.println("狗狗饿了,要吃大骨头");
}
public void food() {
int i=0;
while(this.getHealth()<100){
this.setHealth(getHealth()+3);
if (this.getHealth()>100) {
this.setHealth(100);
}
i++;
}
System.out.println("小狗吃了"+i+"个骨头之后,健康值为"+this.getHealth());
}
//构造方法
public Dog() {
// TODO 自动生成的构造函数存根
}
public Dog(int health) {
this.setHealth(health);
}
}
package day10.Test1;
public class Penguin extends Pet{
@Override
public void eatFoods() {
// TODO 自动生成的方法存根
System.out.println("企鹅饿了,要吃小鱼");
}
public void food() {
int i=0;
while(this.getHealth()<100){
this.setHealth(getHealth()+5);
if (this.getHealth()>100) {
this.setHealth(100);
}
i++;
}
System.out.println("企鹅吃了"+i+"个小鱼头之后,健康值为"+this.getHealth());
}
//构造方法
public Penguin() {
// TODO 自动生成的构造函数存根
}
public Penguin(int health) {
this.setHealth(health);
}
}
package day10.Test1;
//将父类作为形参
public abstract class Pet {
//属性
private int health;
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
//构造方法
public Pet() {
// TODO 自动生成的构造函数存根
}
public Pet(int health) {
this.health=health;
}
//抽象方法
//喂食
public abstract void eatFoods();
}
package day10.Test1;
public class Master {
//喂食
public void feed(Pet pet) {
pet.eatFoods();
if (pet instanceof Dog) {
Dog dog=(Dog)pet;
dog.food();
}else if (pet instanceof Penguin) {
Penguin pen=(Penguin)pet;
pen.food();
}
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
//初始化master对象
Master mas=new Master();
//初始化dog对象
Dog dog=new Dog(89);
Pet pet=dog;
mas.feed(pet);
Penguin pen=new Penguin(76);
Pet pet1=pen;
mas.feed(pet1);
}
}
输出结果:
3.2第二题
自定义类和方法,使用父类作为返回值实现打印不同类型商品价格功能
父类:Goods(商品类)
子类:TVs(电视类)、Foods(食品类)
package day10.Test2;
//子类
public class TVs extends Goods{
@Override
public void print() {
// TODO 自动生成的方法存根
System.out.println("购买电视的账单");
System.out.println("名字:"+this.getName()+"\t价格"+this.getPrice());
}
//构造方法
public TVs() {
// TODO 自动生成的构造函数存根
}
public TVs(String name,int price) {
this.setName(name);
this.setPrice(price);
}
}
package day10.Test2;
public class Foods extends Goods{
@Override
public void print() {
// TODO 自动生成的方法存根
System.out.println("购买食品的账单");
System.out.println("名字:"+this.getName()+"\t价格"+this.getPrice());
}
//构造方法
public Foods() {
// TODO 自动生成的构造函数存根
}
public Foods(String name,int price) {
this.setName(name);
this.setPrice(price);
}
}
package day10.Test2;
//父类
public abstract class Goods {
//属性
private int price;
private String name;
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
//构造方法
public Goods() {
// TODO 自动生成的构造函数存根
}
public Goods(String name,int price) {
this.name=name;
this.price=price;
}
//打印功能
public abstract void print();
}
package day10.Test2;
//测试类
public class TestDemo {
//将父类作为返回值返回
public static Goods getType(int type) {
if (type==1) {
//初始化TVs对象
TVs tv=new TVs("TCL",3999);
return tv;
}else if(type==2){
Foods food=new Foods("方便面",5);
return food;
}
return null;
}
public static void main(String[] args) {
// TODO 自动生成的方法存根
getType(1).print();
getType(2).print();
}
}
输出结果:
3.3第三题
package day10.Test3;
//子类
public class SharedBicycle extends Share{
int hour;
public SharedBicycle() {
// TODO 自动生成的构造函数存根
}
public SharedBicycle(int min,double price) {
this.setMin(min);
this.setPrice(price);
}
@Override
public double checkOut() {
// TODO 自动生成的方法存根
//时间换算
if (this.getMin()%60==0) {
hour=this.getMin()/60;
}else {
hour=this.getMin()/60+1;
}
//计算费用
this.setMoney(hour*getPrice());
return this.getMoney();
}
}
package day10.Test3;
public class SharedCar extends Share{
//属性
private int distance;
public int getDistance() {
return distance;
}
public void setDistance(int distance) {
this.distance = distance;
}
//构造方法
public SharedCar() {
// TODO 自动生成的构造函数存根
}
public SharedCar(int min,int price,int distance) {
this.setMin(min);
this.setPrice(price);
this.setDistance(distance);
}
@Override
public double checkOut() {
// TODO 自动生成的方法存根
if (this.getMin()%10==0) {
this.setMin(getMin()/10);
}else {
this.setMin(getMin()/10+1);
}
//计算经济
if (distance<=10) {
this.setMoney(getMin()*this.getPrice());
}else {
this.setMoney(getMin()*this.getPrice()+(distance-10)*1);
}
return this.getMoney();
}
}
package day10.Test3;
//父类
public abstract class Share {
private int min;
private double price;
private double money;
public int getMin() {
return min;
}
public void setMin(int min) {
this.min = min;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
public double getMoney() {
return money;
}
public void setMoney(double money) {
this.money = money;
}
//构造方法
public Share() {
// TODO 自动生成的构造函数存根
}
public Share(int min,int price) {
this.min=min;
this.price=price;
}
//方法
public abstract double checkOut() ;
}
package day10.Test3;
public class People {
//驾车
public void drive(Share s) {
System.out.println("需要支付"+s.checkOut()+"元");
}
}
package day10.Test3;
public class TestDemo {
public static void main(String[] args) {
// TODO 自动生成的方法存根
People p=new People();
//初始化share对象
SharedBicycle bicycle=new SharedBicycle(100,0.6);
Share s1=bicycle;
p.drive(s1);
SharedCar car=new SharedCar(120,1,150);
Share s2=car;
p.drive(s2);
}
}
输出结果:
4.知识框架