多态及引用数据类型转换

多态及引用数据类型转换,第1张

多态及引用数据类型转换

多态:多种形态

生活中的多态:同一个 *** 作 因为环境不同 产生不同的效果

代码中的多态:同一个方法,因为实际参数或者返回值的不同,产生不同的效果

多态是面向对象三大特征之一,在实际开发中,多态随处可见,多态是提高代码质量重要的手段之一。

多态的表现形式:

1.父类作为形参,实参为子类类型

2.父类作为返回值,实际返回值为子类类型

2.1 父类作为形参
package com.qfedu.test3;

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) {
		super(name, health, love);
		this.strain = strain;
	}

	@Override
	public void print() {
		super.print();
		System.out.println("狗狗的品种是:" + strain);
	}

	public void toHospital() {
		super.toHospital();
		System.out.println("狗狗看病,吃药,吃骨头,健康值恢复!");
		this.setHealth(100);
	}
	
}
package com.qfedu.test3;

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) {
		super(name, health, love); 
		this.sex = sex;
	}
	
	public void print() {
		super.print();
		System.out.println("企鹅的性别是" + sex);
	}
	
	public void toHospital() {
		super.toHospital();
		System.out.println("企鹅看病,打针,疗养,吃小鱼,健康值恢复!");
		this.setHealth(100);
	}
	
}
package com.qfedu.test3;

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() {}
	
	public Pet(String name,int health,int love) {
		this.name = name;
		this.health = health;
		this.love = love;
	}
	
	public void toHospital() {
		System.out.println("宠物看病");
	}
	
	
	
	void print() {
		System.out.println("宠物的名字是:" + name + ",健康值是:" + health);
		System.out.println("宠物的爱心值:" + love );
	}
}
package com.qfedu.test3;

public class Master {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public void cureWithDog(Dog dog) {
		if(dog.getHealth() < 60) {
			dog.toHospital();
		}else {
			System.out.println("狗狗很健康,不需要看病!");
		}
	}
	
	public void cureWithPenguin(Penguin penguin) {
		if(penguin.getHealth() < 60) {
			penguin.toHospital();
		}else {
			System.out.println("企鹅很健康,不需要看病!");
		}
	}
	
	// 观察以上我们写的两个方法?有没有什么不太好的地方?
	// 因为目前是按照一个宠物编写一个看病方法
	// 这样的做法,以后随着系统的迭代更新,我们需要编写更多的方法
	// 来应对系统中更多的宠物,这种写法不符合写代码的<开闭原则>
	// 开闭原则:对扩展开放,对修改源代码关闭
	// 所以:我们应该编写一个"万能"的方法,可以实现给所有的宠物看病
	
	// Pet pet = new Dog();
	public void cure(Pet pet) {
		if(pet.getHealth() < 60) {
			pet.toHospital();
		}else {
			System.out.println("宠物很健康,不需要看病!");
		}
	}
}
package com.qfedu.test3;

public class Test1 {
	public static void main(String[] args) {
		Master zhaosi = new Master();
		zhaosi.setName("赵四");
		
		Dog dog = new Dog("大黄", 55, 20, "大金毛");
		zhaosi.cureWithDog(dog);
		System.out.println(dog.getHealth());
		
		Penguin p = new Penguin("大白", 20, 1, "雌");
		zhaosi.cureWithPenguin(p);
		System.out.println(p.getHealth());
		
	}
}
package com.qfedu.test3;

public class Test2 {
	public static void main(String[] args) {
		Master liuneng = new Master();
		Dog dog = new Dog("大黄", 22, 10, "拉布拉多");
		// 形参为父类 实参为子类 多态表现形式之一
		// 继承的核心思想:子类是父类 子类与父类 是  is a 的关系
		// 这里传入Dog类对象 是类型自动提升 子类自动提升为父类类型
		// 多态向上转型,父类引用指向子类对象
		// 此时可以调用的是子类重写父类的方法
		// 以及继承自父类的方法
		// 不能调用子类独有的方法
		liuneng.cure(dog); 
		System.out.println(dog.getHealth());
		
		Penguin p = new Penguin("小白", 12, 12, "雌性");
		liuneng.cure(p);
		System.out.println(p.getHealth());

	}
}
2.2 父类作为返回值
package com.qfedu.test4;

public class Cat extends Pet{
	private String furColor;

	public String getFurColor() {
		return furColor;
	}

	public void setFurColor(String furColor) {
		this.furColor = furColor;
	}
	
	@Override
	public void toHospital() {
		super.toHospital();
		System.out.println("猫咪看病,吃猫粮,打针,健康值恢复!");
		setHealth(100);
	}
	
}
 
package com.qfedu.test4;

public class Master {
	private String name;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	
	public Dog  giveDog(){
		Dog dog = new Dog("大黄", 100, 100, "金毛");
		return dog;
	}
	
	public Penguin givePenguin() {
		Penguin p = new Penguin("大白", 100, 100, "雌");
		return p;
	}
	
	
	public Cat giveCat() {
		Cat cat = new Cat();
		cat.setName("花花");
		cat.setLove(100);
		cat.setHealth(100);
		cat.setFurColor("绿色");
		return cat;
	}
	
	
	public Tiger giveTiger() {
		return new Tiger();
	}
	// 观察以上代码 我们发现 这种写法依然不符合开闭原则
	// 如果有其他的奖项  我们还要继续编写代码 应对新的奖项
	// 所以我们应该编写一个方法 用于实现所有的奖项
	
	public Pet give(String condition){
		if(condition.equals("一等奖")) {
			Dog dog = new Dog("大黄", 100, 100, "金毛");
			return dog;
		}else if(condition.equals("二等奖")) {
			Penguin p = new Penguin("大白", 100, 100, "雌");
			return p;
		}else if(condition.equals("三等奖")) {
			Cat cat = new Cat();
			cat.setName("花花");
			cat.setLove(100);
			cat.setHealth(100);
			cat.setFurColor("绿色");
			return cat;
		}else if(condition.equals("幸运奖")) {
			return new Tiger();
		}else {
			System.out.println("谢谢!");
			return null;
		}
	}
}
package com.qfedu.test4;

public class Test1 {
	public static void main(String[] args) {
		Master zhaosi = new Master();
		zhaosi.setName("赵四");
		
		// 多态向上转型 父类引用指向子类对象
		// 此时当前对象可以调用的是子类重写父类的方法
		// 以及继承自父类的方法
		// 不能调用子类独有的方法
		Pet dog = zhaosi.give("一等奖");
		dog.print();
		
		Pet penguin = zhaosi.give("二等奖");
		penguin.print();
		
	}
}
3. 引用数据类型转换

自动提升

手动下降

3.1 向上转型

多态向上转型 父类引用指向子类对象

此时当前对象可以调用的是子类重写父类的方法

以及继承自父类的方法

不能调用子类独有的方法

<父类型> <引用变量名> = new <子类型>();

package com.qfedu.test4;

public class Test1 {
	public static void main(String[] args) {
		Master zhaosi = new Master();
		zhaosi.setName("赵四");
		
		// 多态向上转型 父类引用指向子类对象
		// 此时当前对象可以调用的是子类重写父类的方法
		// 以及继承自父类的方法
		// 不能调用子类独有的方法
		Pet dog = zhaosi.give("一等奖");
		dog.print();
		
		Pet penguin = zhaosi.give("二等奖");
		penguin.print();
		
	}
}

3.2 向下转型

向上转型不能访问子类独有的方法,如需 访问,可以向下转型

强制类型转换

为了避免类型转换的错误 我们可以使用instanceof关键字判断类型

避免错误的产生

 

package com.qfedu.test5;

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) {
		super(name, health, love);
		this.strain = strain;
	}

	@Override
	public void print() {
		super.print();
		System.out.println("狗狗的品种是:" + strain);
	}

	public void toHospital() {
		super.toHospital();
		System.out.println("狗狗看病,吃药,吃骨头,健康值恢复!");
		this.setHealth(100);
	}
	
	public void playFlyDisc() {
		System.out.println("狗狗玩飞盘,很开心~");
	}
}

package com.qfedu.test5;

public class Test1 {
	public static void main(String[] args) {
		Master zhaosi = new Master();
		zhaosi.setName("赵四");
		Pet pet1 = zhaosi.give("一等奖"); // 向上转型
		pet1.print();
		
		Dog dog = (Dog)pet1;// 向下转型
		dog.playFlyDisc();
		// 向下转型是将:指向子类对象的父类引用 转换为 子类类型
		// 而不是 将一个父类引用父类对象转换为子类类型
		
		// 当引用数据类型 强制类型转换 应该先使用instanceof关键字判断类型是否可以 正确转换
		// 对象名 instanceof 类名 
		// 表示判断此对象是否属于此类型  如果是返回值为true  否则为false
		Pet pet2 = new Pet();
		
		if(pet2 instanceof Dog) {
			Dog dog1 = (Dog) pet2;
		}else {
			System.out.println("类型错误,不能转换");
		}
		
	}
}

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5716576.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存