一.多态的规则
* 1.类和类之间必须要多继承的关系
* 2.必须要有方法的重写
* 3.(核心)父类的引用(指针) 指向 子类的对象(空间)
创建一个多态对象,看是否能和正常对象一样调用自身的方法!
public static void main(String[] args) {
// 本类的引用(指针)
Cat cat = new Cat();
cat.eat();
// 多态的对象创建方式
// 父类指针指向子类空间
Animal aCat = new Cat();
aCat.eat();
//在这里可以看到以多态的方式创建的对象也可以正常的调用对象中的方法
System.out.println("--------");
Animal aDog = new Dog();
aDog.eat();
}
}
/*
* 需求: 创建 动物类 猫类 狗类 都有一个吃的方法 动物类 动物吃饭 猫 猫吃鱼 狗 狗吃骨头
*/
class Animal {
String name;
String color;
public void eat() {
System.out.println("动物正在吃饭");
}
}
class Cat extends Animal {
@Override
public void eat() {
System.out.println("猫正在吃鱼");
}
}
class Dog extends Animal {
@Override
public void eat() {
System.out.println("狗正在吃骨头");
}
二.多态中如何使用成员变量和方法
public static void main(String[] args) {
//多态创建形式
Father fSon = new Son();
System.out.println(fSon.num);
fSon.print();
System.out.println("-------调皮的分割线-----------");
Son son = new Son();
System.out.println(son.num);
son.print();
}
}
class Father {
int num=20;
public void print() {
System.out.println("我是父类的打印方法");
}
}
class Son extends Father {
int num=10;
public void print() {
System.out.println("我是子类的打印方法");
}
结论:
* 多态 如何使用成员变量
* 父类引用 只能 访问 子类空间中 属于父类的那块空间
* 编译: 编译时要查看父类中是否有这个属性 没有就编译错误
* 运行: 运行时 访问的是父类中 这个成员变量
* 结论:
* 当使用多态形式创建对象的时候 访问成员变量时 编译和运行 都是看父类中的属性
*
* 多态 调用成员方法
* 编译: 编译时 需要看父类中 是否有该方法 没有就报错
* 有就编译通过
* 运行: 运行时 调用的是 子类重写父类的方法
* 结论:
* 编译看父类 运行看子类
三.多态的优缺点
* 多态的弊端:
* 当使用多态的方式创建对象时 无法直接调用子类中特有的方法 原因是创建对象时定义为父类类型(相当于向上提升了)
所以需要向下转型再次变成子类的类型才能调用特有的方法
public static void main(String[] args) {
// 多态的弊端 多态创建对象
// 提升子类对象的类型-->向上转型
Person p = new PianZi();
p.speak();
//如何调用子类的特有方法 向下转型--强制类型转换
PianZi pz=(PianZi)p;
//调用子类的特有方法
pz.hit();
}
}
class Person {
public void speak() {
System.out.println("聊天");
}
}
class PianZi extends Person {
@Override
public void speak() {
System.out.println("洗脑");
}
// 特有方法
public void hit() {
System.out.println("打人,威胁人");
}
* 多态的好处:
* 1.减少代码量 提高工作效率 相当于提高了代码的 可维护性(指得是继承)
* 2.(核心0)提高方法的扩展性
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 wuQi=jian 向上转型
// 可以调用 子类中重写的方法
wuQi.Hit();
// 判断一下类型
// 根据具体的类型 进行 向下转型
// 判断wuQi 是否属于 Jian(类名)这个类的对象
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("练习刀法");
}
}