1. 概念
生活中的多态:同一个动作,指令在不同的环境下,产生不同的效果
程序中的多态:同一段代码,因为实际参数或者具体返回值的不同,产生不同的效果,提升代码的灵活性
2. 表现形式1
1.父类作为形参,子类作为实参
这种方式属于父类引用指向子类对象,属于自动向上转型 Pet pet = new Dog()/new Penguin(); double a = 20;
此时,通过父类的引用,可以访问的是子类重写父类的方法(以及继承父类的方法),不能访问子类独有方法
package com.qfedu.test2;
/**
* 生活中的多态:统一个动作,指令在不同的环境下,产生不同的效果
*
* 程序中的多态:同一段代码,因为实际参数或者具体返回值的不同,产生不同的效果,提升代码的灵活性
*
* 多态的方式:
* 1.父类作为形参,子类作为实参
* 这种方式属于父类引用指向子类对象,属于自动向上转型 Pet pet = new Dog()/new Penguin(); double a = 20;
* 此时,可以通过父类的引用,可以访问的是子类重写父类的方法(以及继承父类的方法),不能访问子类独有方法
* 2.父类作为返回值,子类为实际返回值
* @author WHD
*
*/
public class Pet {
protected String name;
protected int health;
protected 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 void cure() {
System.out.println("宠物看病");
}
void print() {
System.out.println("宠物的名字是:" + name + ",健康值是:" + health + ",爱心值是:" + love);
}
}
package com.qfedu.test2;
/**
* Dog类
* 品种
*
* 无参构造
* 打印信息方法
* @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() {
}
public Dog(String name,int health,int love,String strain) {
this.strain = strain;
super.name = name;
super.health = health;
super.love = love;
}
@Override
public void print(){
super.print();
System.out.println("狗狗的品种是:" + strain);
}
public void cure() {
System.out.println("-------Dog子类重写Pet父类cure方法-------");
super.cure();
System.out.println("狗狗看病,吃药,打针,健康值恢复!");
this.setHealth(100);
this.setLove(100);
}
public void dogM1() {
System.out.println("Dog类m1方法");
}
}
package com.qfedu.test2;
/**
* 企鹅类
* 性别
*
* 无参构造
* 打印信息方法
* @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() {
}
public Penguin(String name,int health,int love,String sex) {
this.sex = sex;
this.name = name;
this.health = health;
this.love = love;
}
public void print() {
super.print();
System.out.println("企鹅的性别是:" + sex);
}
public void cure() {
System.out.println("企鹅看病,打针,疗养,健康值恢复!");
this.setHealth(100);
this.setLove(100);
}
}
package com.qfedu.test2;
/**
* 主人类
* 1.提供有可以带宠物去看病的方法
* @author WHD
*
*/
public class Master {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void toHospitalWithDog(Dog dog) {
dog.cure();
}
public void toHospitalWithPenguin(Penguin penguin) {
penguin.cure();
}
// 分析:以上两个方法可以实现给宠物看病,但是这种方式存在问题,后续如果有新的宠物子类
// 那么必须再次添加新的给宠物看病的方法 ,这种情况不符合"开闭原则"
// 开:对扩展开放
// 闭:对修改源代码关闭
// 所以我们应该考虑编写一个方法 用于实现给所有的宠物看病
public void toHospitalWithPet(Pet pet) { // Pet pet = new Dog(); double a = 20;
pet.cure();
}
}
package com.qfedu.test2;
public class TestPet2 {
public static void main(String[] args) {
Dog dog2 = new Dog("小黄", 65, 30, "金毛");
Penguin p2 = new Penguin("小白", 50, 50, "雌性");
Master guangkun = new Master();
guangkun.toHospitalWithPet(dog2);
guangkun.toHospitalWithPet(p2);
System.out.println(dog2.getHealth() + "---" + dog2.getLove());
System.out.println(p2.getHealth() + "---" + p2.getLove());
}
}
3. 表现形式2
父类作为返回值,子类为实际返回值
这种方式依然属于是向上转型,父类引用指向子类对象
package com.qfedu.test3;
/**
* 生活中的多态:同一个动作,指令在不同的环境下,产生不同的效果
*
* 程序中的多态:同一段代码,因为实际参数或者具体返回值的不同,产生不同的效果,提升代码的灵活性
*
* 多态的方式:
* 2.父类作为返回值,子类为实际返回值
* @author WHD
*
*/
public class Pet {
protected String name;
protected int health;
protected 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 void cure() {
System.out.println("宠物看病");
}
void print() {
System.out.println("宠物的名字是:" + name + ",健康值是:" + health + ",爱心值是:" + love);
}
}
package com.qfedu.test3;
/**
* Dog类
* 品种
*
* 无参构造
* 打印信息方法
* @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() {
}
public Dog(String name,int health,int love,String strain) {
this.strain = strain;
super.name = name;
super.health = health;
super.love = love;
}
@Override
public void print(){
super.print();
System.out.println("狗狗的品种是:" + strain);
}
public void cure() {
System.out.println("-------Dog子类重写Pet父类cure方法-------");
super.cure();
System.out.println("狗狗看病,吃药,打针,健康值恢复!");
this.setHealth(100);
this.setLove(100);
}
public void dogM1() {
System.out.println("Dog类m1方法");
}
@Override
public String toString() {
return "Dog [strain=" + strain + ", name=" + name + ", health=" + health + ", love=" + love + "]";
}
}
package com.qfedu.test3;
/**
* 企鹅类
* 性别
*
* 无参构造
* 打印信息方法
* @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() {
}
public Penguin(String name,int health,int love,String sex) {
this.sex = sex;
this.name = name;
this.health = health;
this.love = love;
}
public void print() {
super.print();
System.out.println("企鹅的性别是:" + sex);
}
public void cure() {
System.out.println("企鹅看病,打针,疗养,健康值恢复!");
this.setHealth(100);
this.setLove(100);
}
@Override
public String toString() {
return "Penguin [sex=" + sex + ", name=" + name + ", health=" + health + ", love=" + love + "]";
}
}
package com.qfedu.test3;
/**
* 主人类
* 1.提供有可以带宠物去看病的方法
* @author WHD
*
*/
public class Master {
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void toHospitalWithPet(Pet pet) {
pet.cure();
}
// 需求:宠物店开业活动大酬宾 抽奖送宠物
// 一等奖 送雌性企鹅一只
// 二等奖 送雄性狗狗一只
// 三等奖 送猫咪一只
// 幸运奖 送成年东北虎一只
public Penguin givePenguin(){
Penguin p1 = new Penguin("大白", 100, 100, "雌性");
return p1;
}
public Dog giveDog(){
Dog dog = new Dog("大黄", 100, 100, "藏獒");
return dog;
}
public Cat giveCat() {
return new Cat();
}
public Tiger giveTiger() {
return new Tiger();
}
// 分析: 以上代码可以实现赠送宠物 但是这种方式同样不符合开闭原则
// 因为后续如果有其他的奖项 还需要再编写代码实现
// 所以我们应该编写一个方法 用于实现所有的宠物赠送
public Pet givePet(String str) {
if(str.equals("一等奖")) {
Penguin p1 = new Penguin("大白", 100, 100, "雌性");
return p1;
}else if(str.equals("二等奖")) {
Dog dog = new Dog("大黄", 100, 100, "藏獒");
return dog;
}else if(str.equals("三等奖")) {
return new Cat();
}else if(str.equals("幸运奖")) {
return new Tiger();
}
return null;
}
public double m1(double a ) {
return 20;
}
}
package com.qfedu.test3;
public class TestPet {
public static void main(String[] args) {
Master zhaosi = new Master();
Pet penguin1 = zhaosi.givePet("一等奖"); // 父类引用指向子类对象 向上转型
System.out.println(penguin1);
Pet dog1 = zhaosi.givePet("二等奖");
System.out.println(dog1);
System.out.println(zhaosi.givePet("三等奖"));
}
}
4. 向下转型
回顾多态的两种表现形式,都属于向上转型(自动提升),父类引用指向子类
此时可以访问的是,继承父类的方法 和 子类重写父类的方法
但是,不能访问子类独有的方法,如果需要访问子类独有的方法
必须向下转型(手动下降)
package com.qfedu.test4;
/**
* Dog类
* 品种
*
* 无参构造
* 打印信息方法
* @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() {
}
public Dog(String name,int health,int love,String strain) {
this.strain = strain;
super.name = name;
super.health = health;
super.love = love;
}
@Override
public void print(){
super.print();
System.out.println("狗狗的品种是:" + strain);
}
public void cure() {
System.out.println("-------Dog子类重写Pet父类cure方法-------");
super.cure();
System.out.println("狗狗看病,吃药,打针,健康值恢复!");
this.setHealth(100);
this.setLove(100);
}
@Override
public String toString() {
return "Dog [strain=" + strain + ", name=" + name + ", health=" + health + ", love=" + love + "]";
}
public void playFlyDisc() {
System.out.println("狗狗玩飞盘,很开心~");
}
}
package com.qfedu.test4;
/**
* 生活中的多态:同一个动作,指令在不同的环境下,产生不同的效果
*
* 程序中的多态:同一段代码,因为实际参数或者具体返回值的不同,产生不同的效果,提升代码的灵活性
*
* 回顾多态的两种表现形式,都属于向上转型(自动提升),父类引用指向子类
* 此时可以访问的是,继承父类的方法 和 子类重写父类的方法
* 但是,不能访问子类独有的方法,如果需要访问子类独有的方法
* 必须向下转型(手动下降)
* @author WHD
*
*/
public class Pet {
protected String name;
protected int health;
protected 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 void cure() {
System.out.println("宠物看病");
}
void print() {
System.out.println("宠物的名字是:" + name + ",健康值是:" + health + ",爱心值是:" + love);
}
}
package com.qfedu.test4;
public class TestPet {
public static void main(String[] args) {
Dog dog1 = new Dog("大黄", 100, 100, "二哈");
dog1.playFlyDisc();
Pet dog2 = new Dog("小黄", 100, 100, "拉布拉多");// 只能访问继承父类的方法 和 子类重写父类的方法
Dog dog = (Dog) dog2;
dog.playFlyDisc();
Pet pet = new Pet();
if(pet instanceof Dog) { // instanceof 关键字用于判断 左侧的引用是否属于右侧的类型
Dog dog3 = (Dog) pet;
System.out.println(dog3);
}
System.out.println("hello world");
// dog2.playFlyDisc();
}
}
5. instanceof关键字
instanceof 关键字用于判断 左侧的引用是否属于右侧的类型
用于避免程序中引用数据类型类型转换异常
package com.qfedu.test5;
import com.qfedu.test4.Dog;
/**
*
* @author WHD
*
*/
public class Person {
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 boolean equals(Object obj) {
if(this == obj) {
return true;
}
if(obj instanceof Person) {
Person p1 = (Person) obj;
if(this.getName().equals(p1.getName()) && this.getIdCard().equals(p1.getIdCard())) {
return true;
}
}
return false;
}
public static void main(String[] args) {
Person p3 = new Person("赵四", "4512487812142453");
Dog dog = new Dog("大黄", 100, 100, "金毛");
System.out.println(p3.equals(dog));
}
public Person(String name, String idCard) {
this.name = name;
this.idCard = idCard;
}
public Person() {
}
}
6.返回值相同或者是其子类
package com.qfedu.test6;
public class A {
public Object m1() {
return null;
}
}
class A1 extends A{
public String m1() {
return null;
}
}
class A2 extends A{
public Object m1() {
return null;
}
}