一.多态
1.定义
多态:是一种事物的多种状态或形态
2.前提
1).类与类之间必须有继承关系
2).必须有方法的重写否则就没有意义
3).父类的引用指向子类的空间
public class Day08 {
public static void main(String[] args) {
//父类的引用指向父类的空间
Animal animal = new Animal();
animal.eat(); //输出:吃
//使用多态的形式创建对象,父类的引用指向子类空间
//调用方法最后执行的是子类重写的方法
Animal cat = new Cat();
cat.eat();//输出:吃鱼
Animal dog = new Dog();
dog.eat();//输出:吃骨头
}
}
创建三个类:
动物类 吃
猫类 吃鱼
狗类 吃骨头
class Animal{
//吃的方法
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("吃骨头");
}
}
3.使用多态方法访问成员变量和成员方法
当使用多态形式创建对象时
访问成员变量:
编译时:要看父类中有没有该变量,没有就报错
执行时:最终访问的成员变量是父类中的成员变量
总结:访问成员变量时编译和运行都要看父类的
访问成员方法:
编译时:看父类中有没有该方法
执行时:最终执行的是子类中的方法
总结:访问成员方法时编译看父类的运行看子类的
public class Day08 {
public static void main(String[] args) {
Father father = new Father();
father.print();//输出:我是father类的打印方法
System.out.println(father.num);//输出:10
//引用类型是父类的,那么该引用只能看到属于自己类型的那部分区域
Father sFather = new Son();
sFather.print();//输出:我是son类的打印方法
System.out.println(sFather.num);//输出:10
}
}
class Father{
int num = 10;
public void print() {
System.out.println("我是father类的打印方法");
}
}
class Son extends Father{
int num = 20;
@Override
//print方法的重写
public void print() {
System.out.println("我是son类的打印方法");
}
}
内存表现见下图:
4.多态的好处和弊端
好处:
1.提高工作效率,增强代码的复用性
2.增强方法的扩展性(使用父类当做方法的参数时可以增强方法的扩展性)
弊端:
1.使用多态的形式无法调用子类的特有方法
public class Day08 {
public static void main(String[] args) {
Person person = new PZ();//将子类的对象做了个向上转型
person.speak();//调用共有方法
//person.hit();//调用特有方法报错
//使用多态的形式无法调用子类的特有方法需要将转上去的类型赚回来
//注意:必须现有向上转型才能向下转型
PZ pz = (PZ)person;//向下转型
pz.hit();//输出:打人
}
}
//创建三个类
class Person{
public void speak() {
System.out.println("聊天");
}
}
//继承person类
class PZ extends Person{
@Override
speak方法的重写
public void speak() {
System.out.println("洗脑");
}
//特有方法
public void hit() {
System.out.println("打人");
}
}
多态的好处:使用父类当做方法参数,该方法可以接收武器类的所有子类对象
public class Day08 {
public static void main(String[] args) {
Dao dao = new Dao();
jianZB(dao);
Jian jian = new Jian();
jianZB(jian);
}
//通用捡装备的方法
//使用父类当做方法参数,该方法可以接收武器类的所有子类对象
public static void jianZB(WuQi wq) {
wq.hit();
//调用子类的特有方法
//做一个类型判断
//instanceof
//判断前面的对象属不属于这个类的对象,类型一致返回true,反之false
if (wq instanceof Dao) {
//类型一致才能进行向下转型
Dao dao = (Dao)wq;
dao.lianDao();
}else if (wq instanceof Jian) {
Jian jian = (Jian)wq;
jian.lianJian();
}
}
}
//武器类
class WuQi{
public void hit() {
System.out.println("打");
}
}
//刀类
class Dao extends WuQi{
@Override
public void hit() {
System.out.println("砍砍砍");
}
//特有方法
public void lianDao() {
System.out.println("练刀");
}
}
//剑类
class Jian extends WuQi{
@Override
public void hit() {
System.out.println("刺刺刺");
}
//特有的方法
public void lianJian() {
System.out.println("练剑");
}
}