多态特点及注意事项

多态

指的是一种事物的多种形态(状态)

例子:卵-->蝌蚪-->青蛙-->青蛙妈妈

实现多态的前提

1.类与类必须有继承关系

2.必须有方法的重写

核心:父类的指针(引用) 指向 子类的 对象(子类的空间)

public class Demo01 {
	public static void main(String[] args) {
		//本类的引用(指针)指向本类的对象(空间)
		Man man = new Man();
		man.eat();
		//多态的对象创建方法
		//父类指针指向子类的空间
		Person1 aman = new Man();//父类的 引用(指针)  指向  子类对象(子类的空间)
		aman.eat();
		Person1 awoman= new Woman();
		awoman.eat();
	}
}

/*
 * 需求: 创建 人类 男人类 女人类 都有一个吃的方法 人类 动物吃饭 男人 男人喝酒 女 女人化妆
 */
class Person1 {
	public void eat() {
		System.out.println("人吃饭");
	}
}

class Man extends Person1 {
	public void eat() {
		System.out.println("男人喝酒");
	}
}

class Woman extends Person1 {
	public void eat() {
		System.out.println("女人化妆");
	}
}

多态如何使用成员变量

父类的引用指向子类的空间中 父类的那部分

编译:在子类中寻找父类的属性 如果找不到 就报错

运行:访问的是父类的成员变量 

结论:当使用多态创建对象时 访问的成员变量 编译和运行都看父类

多态调用成员方法

编译:在子类中寻找父类的 成员方法 如果找不到就报错

运行:看子类的重写父类的方法

结论:重写方法时 编译看父类 运行看子类

public class Demo02 {
	public static void main(String[] args) {
		//多态的创建形式(画内存图)
		Father fSon = new Son();
		fSon.print();
		System.out.println(fSon.num);
		Son son = new Son();
		son.print();
		System.out.println(son.num);
	}
}

class Father {
	int num = 10;

	public void print() {
	System.out.println("我是父类的打印方法");
	}
}

class Son extends Father {
	int num = 20;

	@Override
	public void print() {
		System.out.println("我是子类的打印方法");
	}
}

多态的好处:

1.提高代码的复用性 提高效率 代码的维护性加强(继承)

2.代码的扩展性增强

坏处:使用多态方法创建对象时不能直接调用子类的特有方法

注意:使用多态调用方法时必须先向上转型 在向下转

 
 

public class Demo03 {

public static void main(String[] args) { //多态对象创建 //提升骗子逼格 //提升子类对象的类型 --向上转型 Person p = new PianZi(); p.speak(); //如何调用子类特有方法 //把骗子打回原形 //向下转型---强制类型转换 PianZi pianZi=(PianZi)p; //调用子类的特有方法 pianZi.hit(); } } class Person{ public void speak() { System.out.println("聊天"); } } class PianZi extends Person{ public void speak() { System.out.println("洗脑"); } //特有方法 public void hit() { System.out.println("打人 威胁人"); } }

多态的核心特点:提高方法扩展性;

举个例子

public class Demo04 {
	public static void main(String[] args) {
		Jian jian = new Jian();
		fun(jian);
		Dao dao = new Dao();
		fun(dao);
		
	}

	// 使用多态的方法
	public static void fun(WuQi wuQi) {
		//调用子类中重写的方法
		wuQi.hit();
		//判断一下类型
		//根据具体的类型进行向下转型
		//判断 wuQi 是否属于 剑(类名)这个类的对象
		if (wuQi instanceof Jian) {
			//改武器就是一把剑
			//向下转型
			Jian j=(Jian)wuQi;
			//调用特有的方法
			j.LianJian();
		}else if (wuQi instanceof Dao) {
			Dao d= (Dao)wuQi;
			d.LianDao();
		}
	}
}

class WuQi {
	public void hit() {
		System.out.println("武器打");
	}
}

class Jian extends WuQi {
	@Override
	public void hit() {
		System.out.println("剑-- 舞衣下");
	}

	public void LianJian() {
		System.out.println("练习剑法");
	}
}

class Dao extends WuQi {
	@Override
	public void hit() {
		System.out.println("砍人");
	}

	public void LianDao() {
		System.out.println("练习刀法");
	}
}

上面个例子 扩展性体现在:如果我们要修改调用剑或者刀特有方法 只要从武器这个类入手就行

不需要 单独堆剑 或者 刀 进行分别调用;

下面有个练习 有时间看看

package com.lanou3g;

/*
 * 铁桶僵尸 血量 
 * 方法:每次被打减少2滴血 直到被打死 打印铁桶死了
 * 
 * 门框僵尸
 * 血量
 * 方法:每次被打减少5滴血 直到被打死 打印 门框死了
 * 
 * main函数中 封装一个 打僵尸的方法
 * 无参 有参 set get
 */
public class Demo07 {
	public static void main(String[] args) {
		TieTong tieTong = new TieTong();
		tieTong.setBlood(200);
		hiJiang(tieTong);
	}
	public static void hiJiang(JiangShi jiangShi) {
		jiangShi.hit();
	}
}

class JiangShi {
	// 成员变量私有化
	private int blood;
	// 无参 有参

	public JiangShi(int blood) {
		super();
		this.blood = blood;
	}

	public JiangShi() {
		super();
		// TODO Auto-generated constructor stub
	}

	public void hit() {
		System.out.println("僵尸被人殴打");
	}

	// set get 方法
	public int getBlood() {
		return blood;
	}

	public void setBlood(int blood) {
		this.blood = blood;
	}

	@Override
	public String toString() {
		return "Jiang [blood=" + blood + "]";
	}

}

class TieTong extends JiangShi {
	// 被打方法重写
	@Override
	public void hit() {
		while (true) {
			//判断血量
			if (this.getBlood() <= 0) {
				System.out.println("铁桶僵尸死了");
				break;//结束
			}
			//一次2滴血
			this.setBlood(this.getBlood() - 2);
			System.out.println("僵尸剩余血量" + this.getBlood());
		}
	}
}

class MengKuang extends JiangShi {
	//别打方法重写
	@Override
	public void hit() {
		//判断血量
		if (this.getBlood() <= 0) {
			System.out.println("僵尸死了");
			return;//结束
		}
		//打一次减少5滴血
		this.setBlood(this.getBlood() - 5);
		System.out.println("僵尸剩余血量" + this.getBlood());
		this.hit();//调自己

	}
}

猜你喜欢

转载自blog.csdn.net/shanwenfengyu/article/details/80289348
今日推荐