day15 方法重写和多态(三)

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;
	}
}

请雅清同学过目!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值