java中的多态

# 原创,转载请留言联系

面向对象有三大特性:继承、封装、多态。

继承与封装都比较容易理解,那么应该理解多态呢?

多态,其实就是一个事物的多种形态。例如,一只猫,你可以叫它一只猫,也可以叫它一只动物。

多态在java中是怎么体现的呢?

需要满足三个前提:

1.要有继承关系

2.要有方法重写

3.父类引用指向子类对象

示例:

public class Demo {
    public static void main(String[] args){
        Animal a = new Cat();    // 父类引用子类对象。猫可以是动物
        a.eat();
    }
}

class Animal{
    public void eat(){
        System.out.println("动物吃东西");
    }
}

class Cat extends Animal{    // 有继承关系
    public void eat(){       // 有方法重写
        System.out.println("猫吃鱼");
    }
}

这就是多态的经典例子。最重要的是父类引用子类对象。

 

  • 多态中的成员访问特点

1.成员变量

编译看左边,运行看左边

public class Demo2 {
    public static void main(String[] args){
        Dad d = new Son();
        System.out.println(d.num);
    }
}

class Dad{
    int num = 10;
    public void show(){
        System.out.println("Dad");
    }
}

class Son extends Dad{
    int num = 20;
    public void show(){
        System.out.println("Son");
    }
}

输出结果是10

 

2.成员方法

编译看左边,运行看右边

public class Demo2 {
    public static void main(String[] args){
        Dad d = new Son();
        d.show();
    }
}

class Dad{
    int num = 10;
    public void show(){
        System.out.println("Dad");
    }
}

class Son extends Dad{
    int num = 20;
    public void show(){
        System.out.println("Son");
    }
}

输出结果是:Son

 

3.静态方法

编译看左边,运行看左边

public class Demo2 {
    public static void main(String[] args){
        Dad d = new Son();
        d.show();    // 相当于Dad.show()
    }
}

class Dad{
    int num = 10;
    public static void show(){
        System.out.println("Dad");
    }
}

class Son extends Dad{
    int num = 20;
    public static void show(){
        System.out.println("Son");
    }
}

输出结果:Dad

 

  • 向上转型与向下转型

1.向上转型。

向上转型其实就是父类引用子类对象。

public class Demo2 {
    public static void main(String[] args){
        Dad d = new Son();  // 向上转型
    }
}

class Dad{
    int num = 10;
    public void show(){
        System.out.println("Dad");
    }
}

class Son extends Dad{
    int num = 20;
    public void show(){
        System.out.println("Son");
    }

    public void play(){
        System.out.println("玩耍");
    }
}

 

2.向下转型。

如上面的例子所示,如果我们想要打印子类的num,调用子类的play()方法时,使用d.num打印的是父类的num值,而且d.play()直接出错了,因为父类没有play()方法,编译的时候不能通过。

有什么解决方案呢?(访问子类独有的属性与方法)

如果对象是Son类的对象就没有这些问题了。

所以我们要向下转型。(这就是多态的弊端)

示例:

public class Demo2 {
    public static void main(String[] args){
        Dad d = new Son();
        Son s = (Son) d;    // 向下转型
        System.out.println(s.num);
        s.play();
    }
}

class Dad{
    int num = 10;
    public void show(){
        System.out.println("Dad");
    }
}

class Son extends Dad{
    int num = 20;
    public void show(){
        System.out.println("Son");
    }

    public void play(){
        System.out.println("玩耍");
    }
}

输出结果:

20

玩耍

 

我们为什么要转型来转型去呢?直接Son s = new Son();不就好了吗?

别急,来看看多态的好处就知道了。

 

  • 多态的好处

假如有这么一个场景。

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("狗吃骨头");
    }
}

如果你需要创建10个猫对象,并且调用eat()方法,原始做法是这样的:

public class Demo {
    public static void main(String[] args){
        Cat c1 = new Cat();
        c1.eat();
        Cat c2 = new Cat();
        c2.eat();
        ......
    }

然后你觉得很麻烦,你写了一个方法来改善它,

public class Demo {
    public static void main(String[] args){
        method(new Cat());
        method(new Cat());
    }
    public static void method(Cat c){
        c.eat();
    }
}

这时候,又有需求,你要创建10个Dog对象,并调用eat()方法。

你不得已,又写了一个方法:

public class Demo {
    public static void main(String[] args){
        method(new Cat());
        method(new Cat());
        method2(new Dog());
        method2(new Dog());
    }
    public static void method(Cat c){
        c.eat();
    }
    public static void method2(Dog d){
        d.eat();
    }
}

这时候,又有一大堆需求,又新增猪类,鸡类,鸭类,继承Animal......你不再想写方法了。这时候多态的作用就来了。

多态改善后:

public class Demo {
    public static void main(String[] args){
        method(new Cat());
        method(new Cat());
        method(new Dog());
        method(new Dog());
    }
    public static void method(Animal a){
        a.eat();
    }
}

这就是多态的好处了,可以提高代码的扩展性。

 

  • 最后总结

开发的时候很少在创建对象的时候用父类引用指向子类对象,直接创建子类对象更方便,可以使用子类中特有的属性与方法。当作参数的时候用多态最好,因为扩展性强。

 

posted @ 2019-01-06 15:05  苦瓜爆炒牛肉  阅读(214)  评论(0编辑  收藏  举报