Java基础——多态

1. 多态是继封装、继承之后,面向对象的第三大特性。 

    通俗理解:员工,员工是人的一种,则一个具体的员工老王既是员工也是人,即出现两种形态。Java作为面向对象的语言,同样可以描述一个事物的多种形态。如Employee类继承了Person类,一个Employee的对象便既是Employee也是Person。

    代码当中能体现多态性,其实就是一句话:父类引用指向子类对象

2.前提条件:extends继承或implements实现

    注意:在使用多态后的父类引用变量调用方法时,会调用子类重写后的方法。

3.多态的格式:

    父类类型 变量名=new 子类名称();

    接口名称 变量名=new 实现类名称();

    很多同学在刚开始学习多态时会产生一个问题:这玩意有啥子用?

4.多态的好处:简单地通过一个例子说明

public class Test {
public static void main(String[] args) {
Test test = new Test();
//使用多态
test.func(new Dog());//相当于Animal animal = new Dog();
test.func(new Cat());//相当于Animal animal = new Cat();
// 不使用多态
// test.eatMethod(new Dog());
// test.eatMehtod(new Cat());
}
​
//使用多态只需造一个方法
public void func(Animal animal) {
animal.eat();
}
​
// 如果没有多态性,需要造很多重载的方法(这里只单纯举了两个子类,要是有很多个子类那就麻烦了,父子关系被淡化)
// public void eatMethod(Dog dog) {
// dog.eat();
// }
//
// public void eatMehtod(Cat cat) {
// cat.eat();
// }
​
}
​
class Animal {
public void eat() {
System.out.println("动物,吃饭");
}
}
​
class Dog extends Animal {
public void eat() {
System.out.println("狗吃肉");
}
}
​
class Cat extends Animal {
public void eat() {
System.out.println("猫吃鱼");
}
}
输出结果:
狗吃肉
猫吃鱼

5.多态访问成员变量的特点:编译看左边,运行看右边

    通过对象名称访问成员变量,看等号左边是谁则优先使用谁,没有则向上找。

public class Test {
    public static void main(String[] args) {
        Zi zi = new sun();
        System.out.println(zi.num);//等号左边是Zi,但Zi没有num变量,向上找Fu,Fu有num,输出Fu的num
    }
}
​
class Fu {
    int num = 0;
}
​
class Zi extends Fu {
​
}
​
class sun extends Zi {
    int num = 1;
}
输出结果:
0

6.多态访问成员方法的特点:编译看左边,运行看右边

    看new的是谁,就优先使用谁,没有则向上找。

public class Test {
    public static void main(String[] args) {
        Fu fu = new Zi();
        fu.func();//new的是Zi,则使用Zi类中的func方法
        fu.method();//new的是Zi,但Zi类中没有method方法,则向上找Fu类,因此调用Fu类的method方法
    }
}
​
class Fu {
    public void method() {
        System.out.println("这是父类的method方法。");
    }
​
    public void func() {
        System.out.println("这是父类的func方法。");
    }
}
​
class Zi extends Fu {
    public void func() {
        System.out.println("这是子类的方法。");
    }
}
输出结果:
这是子类的方法。
这是父类的method方法。

7.多态的两种转型

    向上转型:其实多态本身就是向上转型的过程。

        格式:父类类型 变量名=new 子类类型();

       适用场景:当不需要面对子类类型时,通过提高扩展性,或者使用父类的功能就能完成相应的操作。通俗来讲:创建一个子类对象,把它当作父类来使用。

     注意:向上转型一定是安全的,从小范围转为大范围。类似于:double num = 100;//正确,int-->double,自动类型转换。但是!!!一旦向上转型为父类,就无法调用子类原本特有的方法,例如:

public class Test {
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();//猫吃鱼
        animal.catchMouse();//报错,一旦向上转型为父类,就无法调用子类原本特有的方法
    }
}
​
class Animal {
    public void eat() {
        System.out.println("动物,吃饭。");
    }
}
​
class Cat extends Animal {
    public void eat() {
        System.out.println("猫吃鱼。");
    }
​
    //子类Cat特有的方法
    public void catchMouse() {
        System.out.println("猫会抓老鼠。");
    }
}
​
class Dog extends Animal {
    public void eat() {
        System.out.println("狗吃肉。");
    }
}

        有时候向上转完后悔了,想向下转,这时就需要用到向下转型【还原】。(这里的还原需要强调一下,本来是猫就是猫,不能向下转型时却变成了狗。)

    向下转型: 一个已经向上转型的子类对象可以使用强制类型转换的格式,将父类引用类型转为子类引用各类型。

        格式:子类类型 变量名=(子类类型) 父类类型的变量;

        适用场景:当要使用子类特有功能时。

    注意:必须保证向下转型是同一个类,如果非要向下转型到其他类,会抛出ClassCastException异常(类转换异常)。类似于:int num = (int) 10.0;//正确      int num = (int) 10.9;//错误,会出现精度损失。

//对上面例子的main方法进行补充
    public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();//猫吃鱼
        animal.catchMouse();//报错,一旦向上转型为父类,就无法调用子类原本特有的方法
        Cat cat = (Cat) animal;
        cat.catchMouse();//猫会抓老鼠。
        //下面演示错误的向下转型,本来new的时候是一只猫,现非要当作狗
        Dog dog = (Dog) animal;//运行时会抛出ClassCastException异常,值得注意的是编译时候不报错
}

   想必到这里大家可能会有一个疑问:那我怎么知道要向下转型的对象本来是什么子类呢?此时可以使用instanceof关键字进行类型判断。

8.instanceof关键字

    格式:对象 instanceof 类名称

    返回值:boolean类型

public static void main(String[] args) {
        Animal animal = new Cat();
        animal.eat();//猫吃鱼
        if (animal instanceof Cat) {
            Cat cat = (Cat) animal;
            cat.catchMouse();//猫会抓老鼠。
        }
}

点击链接获取本章节PDF版本及其练习题:https://download.csdn.net/download/Waylon_Ma/20418533

创作不易,点个关注不迷路~

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Waylon1024

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值