java详解 --- 多态

今天来说说面向对象的最后一个特征:多态

一.多态

1.多态的定义
一种事物的多种形态

2.使用多态的规则
a.两个类之间是继承关系
b.父类的引用是子类的对象
c.要有方法的重写

举例说明:

class Animal{
    public void eat(){
        System.out.println("吃饭");
    }
}

class Cat extends Animal{
    public void eat(){
        System.out.println("吃鱼");
    }
}

class Dog extends Animal{
    public void eat(){
        System.out.println("吃骨头");
    }
}
public class Demo01 {

    public static void main(String[] args) {
        //A:本类的引用 -> 本类的对象
        Cat c = new Cat();
        c.eat();

        //B:父类的引用 -> 子类的对象
        //多态
        Animal a = new Cat();
        a.eat();
    }
}

上例中父类是Animal类,子类是Dog和Cat类,父类和子类中有方法的重写 – eat.
A:用子类名和对象名调用,正常的调用方法
B:用父类名和对象名调用,就是用多态的方法调用的,满足多态的三个规则.

3.多态的调用
A.多态如何调用成员变量(编译和运行都看父类)
多态,当父类引用调用成员变量的时候:
编译 ->在父类中查找有没有这个成员变量,如果没有的话编译是不会通过的
运行 ->如果有这个成员变量,那么访问的就是这个成员变量

B.多态如何调用成员方法(编译看父类,运行看子类)
多态,当父类引用调用成员方法的时候:
编译 ->在父类中查找有没有这个方法,没有就会报错
运行 ->在子类中找相同的方法

举例说明:

class Father{
    //A:如果将该语句注释,系统编译就不会通过
    //调用成员变量的时候,会先从父类中寻找.找不到的话,编译是不会通过的,就会报错
    //运行的时候就会输出10
    int num = 10;

    //B:如果将该语句注释,系统编译就不会通过
    //调用成员方法的时候,会先从父类中寻找.找不到的话,编译是不会通过的,就会报错
    public void speak() {
        System.out.println("Father 说");
    }
}

class Son extends Father{
    int num = 20;

    //B:运行的时候会从子类找相同的语句运行
    public void speak() {
        System.out.println("Son 说");
    }
}
public class Demo02 {
    public static void main(String[] args) {
        Father father = new Son();
        father.speak();
        System.out.println(father.num);

        Son son =new Son();
        son.speak();
        System.out.println(son.num);
    }
}

4.使用多态的好处和弊端
好处:
A.增强代码的可维护性
B.增强方法的可扩展性

弊端:不能直接调用子类的特殊(不是重写父类的)方法,需要执行向下转型

那什么是向下执行呢?

举例说明下什么是向下转型:

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 Demo03 {
    public static void main(String[] args) {
        // 父类引用指向子类对象
        // 骗子的向上转型
        Person p = new PianZi();
        // 骗子自己的方法 对你洗脑
        p.speak();

        // 注意:如果你要向下转型 必须之前有过向上转型
        // 骗子的向下转型
        PianZi pZi = (PianZi)p;
        pZi.hit();
    }
}

由此可以看出,向下转型是在向上转型的基础上才能转的:
向上转型:分类的引用指向子类,相当于把骗子称做普通人,但本质里还是骗子
向下转型:用骗子类调用骗子对象,相当于把骗子的普通人外衣扒了下来.

5.instanceof关键字
instanceof关键字是作为判断用的,是判断一个对象是否属于那一个类,属于就输出true;反之输出false.
举例说明:

class WuQi{
    public void hit() {
        System.out.println("可以挥舞武器");
    }
}

class Dao extends WuQi{
    public void hit() {
        System.out.println("挥舞刀 -- 砍人");
    }
    public void lianGong() {
        System.out.println("练刀");
    }
}

class Jian extends WuQi{
    public void hit(){
        System.out.println("挥剑 -- 刺人");
    }
    public void lianJian() {
        System.out.println("耍剑");
    }
}
public class Demo04 {
    //封装一个创建武器的方法
    public static void fun(WuQi w) {
        w.hit();
        // 判断传下的参数是属于哪个类的
        // 用instanceof关键字
        // 可以判断 是否属于 那个类的对象
        // 判断 w 是否属于 Dao类
        if (w instanceof Dao) {
            // 向下转型成刀
            Dao dao = (Dao)w;
            dao.lianGong();
        }else if (w instanceof Jian) {
            // 向下转型成剑
            Jian jian = (Jian)w;
            jian.lianJian();
        }
    }

    public static void main(String[] args) {
        fun(new Dao());
        fun(new Jian());
    }
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值