多态
1.多态的概念
多态:多种形态
指同一段代码在执行过程中 因为参数或者返回值的不同产生不一样的效果
2.多态实现方法
2.1父类作为形参
在日常开发中,我们通常需要一个方法来解决多个问题,根据参数传入的不同,来实现不同的效果,所以我们可以使用父类作为形参,实参为子类类型,通过这种向上转型的方式来实现。
package com.qfedu.test4;
/**
* 多态
* 程序中的多种形态
* 指同一段代码在执行过程中 因为参数或者返回值的不同 产生不一样的效果
* 多态的表现形式
* 1.父类作为形参
* 2.父类作为返回值
* 生活中的多态
* 同一个动作,因为环境的不同,产生不一样的效果
* @author WHD
*
*/
public class Pet {
private String name;
private int health;
private int love;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
public Pet() {
}
public void cure() {
System.out.println("给宠物看病");
}
@Override
public String toString() {
return "Pet [name=" + name + ", health=" + health + ", love=" + love + "]";
}
}
package com.qfedu.test4;
/**
* 狗类
* 名字
* 健康值
* 爱心值
* 品种
*
* @author WHD
*
*/
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
public Dog m1() {
return null;
}
public Dog(String name,int health,int love,String strain) {
super(name, health, love);
this.strain = strain;
}
public Dog() {
}
public void cure() {
System.out.println("狗狗看病,打针,吃骨头");
this.setHealth(100);
}
public void playFlyDisc() {
System.out.println("狗狗玩飞盘");
}
@Override
public String toString() {
return "Dog [strain=" + strain + "]" + super.toString();
}
}
package com.qfedu.test4;
/**
* 企鹅类
* 名字
* 健康值
* 爱心值
* 性别
* @author WHD
*
*/
public class Penguin extends Pet{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Penguin(String name,int health,int love,String sex ) {
super(name, health, love);
this.sex = sex;
}
public Penguin() {
}
public void cure() {
System.out.println("企鹅看病,疗养,保健品滋补,溜冰");
this.setHealth(100);
}
public void playIce() {
System.out.println("企鹅溜冰……");
}
@Override
public String toString() {
// String petStr = super.toString();
// return "Penguin [sex=" + sex + "]" + petStr;
return "Penguin[name="+super.getName()+",health="+super.getHealth()+",love="+super.getLove()+",sex="+sex+"]";
}
}
package com.qfedu.test4;
/**
* 主人类
* 可以将宠物带到宠物医院 看病
* 多态的表现形式
* 1.父类作为形参
* 属于向上转型 自动实现的 自动提升
* @author WHD
*
*/
public class Master {
/**
* 给狗看病的方法
* @param dog
*/
public void dogToHospital(Dog dog) {
if(dog.getHealth() >= 90) {
System.out.println("健康值ok,不需要看病");
}else {
dog.cure();
}
}
/**
* 给企鹅看病
* @param penguin
*/
public void penguinToHospital(Penguin penguin) {
if(penguin.getHealth() >= 95) {
System.out.println("健康值ok,不需要看病");
}else {
penguin.cure();
}
}
/**
*
* @param cat
*/
public void catToHospital(Cat cat) {
if(cat.getHealth() >= 80) {
System.out.println("健康值ok,不需要看病");
}else {
cat.cure();
}
}
// 以上方法可以实现给宠物看病 但是不符合开闭原则
// 比如随着系统的更新 宠物子类越来越多 那么我们需要频繁的修改主人类的代码
// 这样设计不合理 我们应该写一个方法,用于给所有的宠物看病
/**
* Pet pet形参相当于 引用 也就是对象的 声明
* 实际对象是实参 比如我们要传入一个Dog对象 Pet pet = new Dog(); double a = 20;
* 父类引用指向子类对象 父类作为形参 多态的实现方式之一
* 使用这种方式 代码的灵活性 大大提高了
* @param pet
*/
public void toHospital(Pet pet) {
pet.cure();
}
// 测试多态的形式
public static void main(String[] args) {
Master zhaosi = new Master();
Dog dog = new Dog("大黄", 50, 50, "哈士奇");
zhaosi.toHospital(dog);
System.out.println(dog.getHealth());
Penguin p = new Penguin("小黑", 55, 55, "雌");
zhaosi.toHospital(p);
System.out.println(p.getHealth());
System.out.println("===============================");
}
}
2.2父类作为返回值
在开发中,我们可以编写一个方法根据参数的不同,返回的子类对象也不同,方法声明书写返回值类型作为父类类型,可以提高代码的灵活性,这种放式依然是向上转型,多态的实现方式之一。
package com.qfedu.test4;
/**
* 多态
* 程序中的多种形态
* 指同一段代码在执行过程中 因为参数或者返回值的不同 产生不一样的效果
* 多态的表现形式
* 1.父类作为形参
* 2.父类作为返回值
* 生活中的多态
* 同一个动作,因为环境的不同,产生不一样的效果
* @author WHD
*
*/
public class Pet {
private String name;
private int health;
private int love;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
public Pet() {
}
public void cure() {
System.out.println("给宠物看病");
}
@Override
public String toString() {
return "Pet [name=" + name + ", health=" + health + ", love=" + love + "]";
}
}
package com.qfedu.test4;
/**
* 狗类
* 名字
* 健康值
* 爱心值
* 品种
*
* @author WHD
*
*/
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
public Dog(String name,int health,int love,String strain) {
super(name, health, love);
this.strain = strain;
}
public Dog() {
}
public void cure() {
System.out.println("狗狗看病,打针,吃骨头");
this.setHealth(100);
}
public void playFlyDisc() {
System.out.println("狗狗玩飞盘");
}
@Override
public String toString() {
return "Dog [strain=" + strain + "]" + super.toString();
}
}
package com.qfedu.test4;
/**
* 企鹅类
* 名字
* 健康值
* 爱心值
* 性别
* @author WHD
*
*/
public class Penguin extends Pet{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Penguin(String name,int health,int love,String sex ) {
super(name, health, love);
this.sex = sex;
}
public Penguin() {
}
public void cure() {
System.out.println("企鹅看病,疗养,保健品滋补,溜冰");
this.setHealth(100);
}
public void playIce() {
System.out.println("企鹅溜冰……");
}
@Override
public String toString() {
// String petStr = super.toString();
// return "Penguin [sex=" + sex + "]" + petStr;
return "Penguin[name="+super.getName()+",health="+super.getHealth()+",love="+super.getLove()+",sex="+sex+"]";
}
}
package com.qfedu.test4;
/**
* 主人类
* 可以将宠物带到宠物医院 看病
* 多态的表现形式
* 1.父类作为返回值
* 属于向上转型 自动实现的 自动提升
* @author WHD
*
*/
public class Master {
// 比如现在宠物店搞开业活动 抽奖送宠物
// 一等奖 送企鹅一只
// 二等奖 送狗狗一只
// 三等奖 送雌猫咪一只
/**
* 一等奖 获得企鹅一只
* @return
*/
public Penguin givePenguin() {
Penguin p = new Penguin("小白", 100, 100, "雌");
return p;
}
/**
* 二等奖 送狗狗一只
* @return
*/
public Dog giveDog() {
return new Dog("大黄", 100, 100, "拉布拉多");
}
/**
* 三等奖 送猫咪
* @return
*/
public Cat giveCat(){
return new Cat("花花", 100, 100, "绿色");
}
// 以上三个方法可以实现送宠物 但是依然不符合开闭原则 如果有很多奖项
// 那么将继续书写更多的送宠物的方法 这样设计不合理
// 我们应该书写一个方法 用于赠送所有的宠物
public Pet give(String num) {
if(num.equals("一等奖")) {
return new Penguin("小白", 100, 100, "雌");
}else if(num.equals("二等奖")) {
return new Dog("大黄", 100, 100, "拉布拉多");
}else if(num.equals("三等奖")) {
return new Cat("花花", 100, 100, "绿色");
}
System.out.println("没有这个奖项,将返回null");
return null;
}
// 测试多态的形式
public static void main(String[] args) {
Master zhaosi = new Master();
Pet pet = zhaosi.give("三等奖");
}
}
多态:程序中的多种形态,指同一段代码在执行过程中,因为参数或者返回值的不同,产生不一样的效果
多态的表现形式:
1.父类作为为形参
2.父类作为返回值
生活中的多态:同一个动作,因为环境的不同,产生不一样的效果。
2 .2 父类作为返回值
在开发中,我们可以编写一个方法根据参数不同,返回不同的子类对象,方法声明书写返回值类型为父类类型,可以提升代码的灵活性,。这种方式依然是向上转型,多态的实现方法之一。
package com.qfedu.test4;
/**
* 多态
* 程序中的多种形态
* 指同一段代码在执行过程中 因为参数或者返回值的不同 产生不一样的效果
* 多态的表现形式
* 1.父类作为形参
* 2.父类作为返回值
* 生活中的多态
* 同一个动作,因为环境的不同,产生不一样的效果
* @author WHD
*
*/
public class Pet {
private String name;
private int health;
private int love;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getHealth() {
return health;
}
public void setHealth(int health) {
this.health = health;
}
public int getLove() {
return love;
}
public void setLove(int love) {
this.love = love;
}
public Pet(String name, int health, int love) {
this.name = name;
this.health = health;
this.love = love;
}
public Pet() {
}
public void cure() {
System.out.println("给宠物看病");
}
@Override
public String toString() {
return "Pet [name=" + name + ", health=" + health + ", love=" + love + "]";
}
}
package com.qfedu.test4;
/**
* 狗类
* 名字
* 健康值
* 爱心值
* 品种
*
* @author WHD
*
*/
public class Dog extends Pet{
private String strain;
public String getStrain() {
return strain;
}
public void setStrain(String strain) {
this.strain = strain;
}
public Dog(String name,int health,int love,String strain) {
super(name, health, love);
this.strain = strain;
}
public Dog() {
}
public void cure() {
System.out.println("狗狗看病,打针,吃骨头");
this.setHealth(100);
}
public void playFlyDisc() {
System.out.println("狗狗玩飞盘");
}
@Override
public String toString() {
return "Dog [strain=" + strain + "]" + super.toString();
}
}
package com.qfedu.test4;
/**
* 企鹅类
* 名字
* 健康值
* 爱心值
* 性别
* @author WHD
*
*/
public class Penguin extends Pet{
private String sex;
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
public Penguin(String name,int health,int love,String sex ) {
super(name, health, love);
this.sex = sex;
}
public Penguin() {
}
public void cure() {
System.out.println("企鹅看病,疗养,保健品滋补,溜冰");
this.setHealth(100);
}
public void playIce() {
System.out.println("企鹅溜冰……");
}
@Override
public String toString() {
// String petStr = super.toString();
// return "Penguin [sex=" + sex + "]" + petStr;
return "Penguin[name="+super.getName()+",health="+super.getHealth()+",love="+super.getLove()+",sex="+sex+"]";
}
}
package com.qfedu.test4;
/**
* 主人类
* 可以将宠物带到宠物医院 看病
* 多态的表现形式
* 1.父类作为返回值
* 属于向上转型 自动实现的 自动提升
* @author WHD
*
*/
public class Master {
// 比如现在宠物店搞开业活动 抽奖送宠物
// 一等奖 送企鹅一只
// 二等奖 送狗狗一只
// 三等奖 送雌猫咪一只
/**
* 一等奖 获得企鹅一只
* @return
*/
public Penguin givePenguin() {
Penguin p = new Penguin("小白", 100, 100, "雌");
return p;
}
/**
* 二等奖 送狗狗一只
* @return
*/
public Dog giveDog() {
return new Dog("大黄", 100, 100, "拉布拉多");
}
/**
* 三等奖 送猫咪
* @return
*/
public Cat giveCat(){
return new Cat("花花", 100, 100, "绿色");
}
// 以上三个方法可以实现送宠物 但是依然不符合开闭原则 如果有很多奖项
// 那么将继续书写更多的送宠物的方法 这样设计不合理
// 我们应该书写一个方法 用于赠送所有的宠物
public Pet give(String num) {
if(num.equals("一等奖")) {
return new Penguin("小白", 100, 100, "雌");
}else if(num.equals("二等奖")) {
return new Dog("大黄", 100, 100, "拉布拉多");
}else if(num.equals("三等奖")) {
return new Cat("花花", 100, 100, "绿色");
}
System.out.println("没有这个奖项,将返回null");
return null;
}
// 测试多态的形式
public static void main(String[] args) {
Master zhaosi = new Master();
Pet pet = zhaosi.give("三等奖");
}
}
3.转型
3.1向上转型
向上转型可以访问
1.父类访问权限允许的方法
2.子类重写父类的方法
3.不能调用用子类独有的方法
格式:
父类类型 引用名称 = new子类对象();
Pet pet = new Dog();
3.2向下转型
我们在强转的过程中,有可能会出现类型转换异常ClassCastException,此时我们可以通过instanceof关键字判断,避免错位的产生。
语法格式:
实例名称 instanceof 类型名称 表示判断实例是否属于当前类型 是的话返回true否则返回false比如在重写equals方法的时候,我们必须对参数做判断再强转
package com.qfedu.test1;
/**
* 重写toString和equals方法
* @author WHD
*
*/
public class Student {
private String name; // 名字
private String idCard; // 身份证
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getIdCard() {
return idCard;
}
public void setIdCard(String idCard) {
this.idCard = idCard;
}
public String toString() {
return "Student[name="+name+",idCard="+idCard+"]";
}
public boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof Student) { // 加上判断 解决潜在bug
Student stu = (Student) obj; // 这行代码存在bug
if(this.getName().equals(stu.getName()) && this.getIdCard().equals(stu.getIdCard())) {
return true;
}
}
return false;
}
public static void main(String[] args) {
Student stu1 = new Student();
stu1.setName("赵四");
stu1.setIdCard("454877412312345");
System.out.println(stu1);
Student stu2 = new Student();
stu2.setName("赵四");
stu2.setIdCard("454877412312345");
System.out.println(stu2);
Dog dog = new Dog();
System.out.println(stu1.equals(stu2));
}
}
package com.qfedu.test4;
/**
* 向上转型 自动实现
* 1.可以调用的是 子类重写父类的方法 和 父类访问权限允许的方法
* 2.不能调用子类独有的方法
* 如果想要调子类独有的方法怎么办?
* 向下转型 手动强转
* 可以调用子类独有的方法 和父类访问权限允许的方法 以及重写父类的方法
* @author WHD
*
*/
public class Test1 {
public static void main(String[] args) {
// 向上转型
Dog d1 = new Dog();
Pet dog = new Penguin();
// 子类继承父类的方法
dog.setHealth(100);
dog.setName("花花");
dog.setLove(100);
// 子类重写父类的方法
dog.cure();
// 不能调用子类独有的方法
// dog.setStrain("金毛");
// 向下转型
Dog huahua = (Dog) dog;
huahua.playFlyDisc();
Pet penguin = new Penguin();
Penguin xiaohei = (Penguin) penguin;
xiaohei.playIce();
// 向下转型错误示范 为了避免类型转换的错误发生
// 我们可以通过一个关键字 instanceof 判断是否可以强转
// a instanceof A 表示判断 a 是否属于 A类型 返回值布尔类型
Object obj = new Object();
if(obj instanceof Dog) {
Dog d = (Dog) obj;
}
Pet pet = new Pet();
if(pet instanceof Dog) {
Dog dahuang = (Dog) pet;
}else {
System.out.println("类型不匹配");
}
}
}
向上转型 自动实现
1.可以调用的是 子类重写父类的方法 和 父类访问权限允许的方法
2.不能调用子类独有的方法
如果想调用子类独有的方法怎么办?
向下转型 手动强制
可以调用子类独有的方法 和父类访问权限允许的方法,以以及重写父类的方法
习题,做一个超市系统,安排生活用品,和食品。。。。。。