java多态

Posted 垚垚是小白

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java多态相关的知识,希望对你有一定的参考价值。

java语法中的多态机制[只是基础语法,多态作用在后续讲解]

1:Animal、cat、Bird三个类的关系:
Cat继承Animal
Bird继承animal
cat和Bird没有继承关系
2:面你对对象三大特征:封装,继承,多态
3:关于多态中涉及到的几个概念:
Ⅰ 向上转型,
子类型-》转化为父类型
又被称为:自动转化类型
Ⅱ 向下转型
父类型到子类型
又被称为:强制转换类型【需要加强制转换类型符】
需要记忆:无论向上还是向下都需要有继承关系

Animal类

package com.beijing.javse.test01;
//动物类
public class Animal {
    public void move(){
        System.out.println("动物在移动");
    }
}

Cat类

package com.beijing.javse.test01;
//猫类
public class Cat extends Animal {
    //重写父类中的方法
    public void move(){
        System.out.println("猫在走猫步");
    }
    //不是从父类中继承过来的方法
    //这个方法是子类对象特有的【不是说所有的端午都能抓老鼠】
    public void catchMouse(){
        System.out.println("猫抓老鼠");
    }
}

Bird类

package com.beijing.javse.test01;

public class Bird extends Animal{
    //重写方法
    public void move(){
        System.out.println("鸟儿在飞翔");
    }
    /*
    子类对象特有的方法
     */
    public void fly(){
        System.out.println("bird fly");
    }
}

Test类

package com.beijing.javse.test01;

import java.util.concurrent.Callable;

public class Test {
    public static void main(String[] args) {
        //以前编写程序
  Animal a1=new Animal();
  a1.move();
        Cat c1=new Cat();
        c1.move();
        Bird b1=new Bird();
        b1.move();

        //使用多态语法机制
        /*
        1:Animal和cat是继承关系
        2:cat is aanimal
        3:new cat()创建对象类型是Cat,a2这样引用数据类型是animal
        可见土木进行了类型转换,子类转换成父类,称为向上转型
        4:java中允许这种语法,父类型引用指向子类型的对象
         */
        Animal a2=new Cat();//右边赋值给左边
        //子类到父类,向上转型
        /*
        1.java程序永远分为编译阶段和运行阶段
        2:先分析编译阶段,在分析运行阶段。编译无法通过,根本不能运行
        3:编译器检查这个a2这个引用的数据类型为Animal.class字节码当中有,所以建议通过了
        只有静态绑定成功之后才有后续的运行
        4:在程序运行当中,Jvm堆内存当中真实创建的对象是Cat对象,以下程序
        运行阶段一定会调用Cat对象的move()方法,此事发生了动态绑定
        5:无论Cat有没有move()重写,运行阶段一档调用的是Cat对象的move方法,
        因为底层真实对象就是Cat对象。
        6:父类型引用指向子类型对象这种机制导致程序存在编译阶段和运行阶段绑定两种不同的类型
        */
        a2.move();//猫在走猫步  a2编译为Animsl类型,运行的是Cat类
        //a2.catchMouse();//编译都没有通过
        /*
        需求:假设想让以上对象执行catchMouse,怎么办?
           a2是无法直接调用的,因为a2的类型Animal中没有这个方法
           我们可以将a2强制转换为Cat类型
           a2的类型是animal,转换为子类Cat,称为向下转型
           需要加强制类型转换符。

           什么时候需要使用向下转型呢?
           当调用的方法是子类型当中特有的,在父类中不存在。必须进行向下转型
           Cat c2=(cat)a2;

         */
        Cat c2=(Cat)a2;
        c2.catchMouse();
       // [父类型引用指向子类型对象]【多态】
        /*
        1:一下程序编译时没有问题的,因为编译器检查数据类型时animal
        animal和cat之间存在继承关系,并且animal时父类型,cat时子类型
        2:程序虽然编译通过了,但是程序在运行阶段会出现问题,因为真实对象时bird类型
         cat和bird没有继承关系,不能转换

         */
        Animal a3=new Bird();
        //Cat c3=(Cat)a3;//运行不会通过,bird和cat没关系
        /*
        1:以上异常中只有在强制类型转换的时候才会发生,向下转型
         2:向上转型只要编译通过,运行一定不会出问题,但是向下转型不一定
         3:怎么避免向下转型出现异常呢?
           使用instanceof运算符可以避免出现异常
         4:instanceof运算符怎么用?
             5.1语法格式
                (引用instanceof数据类型名)
                5.2以上运算符的执行类型时布尔类型,结果可能是true/false
                5.3关于运算结果true/false:
                假设:(a instanceof  Animal)
                true表示:这个a引用指向的时一个animal类型
                false表示:a不是
          6:java规范中要求进行强制类型转换之前,建议采用instanceof进行判断
         这是
         */
        if(a3 instanceof  Cat){
          Cat c3=(Cat)a3;
          c3.catchMouse();
        }else
                if(a3 instanceof  Bird){
                    Bird b2=(Bird)a3;
                    b2.fly();
            }

    }
    }

Test02类

package com.beijing.javse.test01;

public class Test02 {
    public static void main(String[] args) {
        //父类型引用指向子类型对象
        //向上转型
        Animal a1 = new Cat();
        Animal a2 = new Bird();
              //向下转型
        if (a1 instanceof Cat) {
            Cat c1 = (Cat)a1;
        }
        if(a2 instanceof  Bird){
            Bird b1=(Bird)a2;
        }
    }
}

多态的作用

Cat类

package com.beijing.javase;

//宠物小猫
public class Cat {
    public void eat(){
        System.out.println("小猫正在吃鱼");
    }
}

Master类

package com.beijing.javase;
//这种方式没有使用java语言中的多态装置,存在缺点:扩展力很差
//只要加上一个新的宠物,Master类就需要添加新的方法
/*public class Master {
    //喂养宠物
    public void feed(Cat c){
        c.eat();
    }
    public void feed(Dog d){
        d.feed();
    }
}*/
//主人类和猫、dog的关联性太大

//降低程序的耦合力,提高程序的扩展力【软件开发最重要的一个目标】
public class Master {
    //喂养宠物的方法
    public void feed(Pet pet){
        pet.eat();
    }
}

Pet类

package com.beijing.javase;

public class Pet {
    //所有的宠物都可以吃
    public void eat(){

    }
}

Dog类

package com.beijing.javase;

public class Dog {
    public  void feed(){
        System.out.println("小狗吃骨头");
    }
}

Test类

package com.beijing.javase;

import java.util.concurrent.Callable;

/*
多态在实际开发中的作用,一下以主人喂养宠物为例说明多态的作用
1:分析:主任喂养宠物这个场景需要进行类型的抽象
主人【类】
主人可以喂养宠物,所以有主人喂养这个动作
宠物【类】
宠物可以吃东西,所以宠物有吃东西这个动作

2:面向对象编程的核心:定义好类,然后将类实例化给对象,给一个环境驱使一下,让各个对象协作起来形成一个系统
3:多态的作用是什么?
降低程序的耦合度,提高程序的拓展力。
能使用多态,尽量使用多态
父类型引用指向子类型对象

核心:面向抽象编程,不要面向具体编程
 */
public class Test {
    public static void main(String[] args) {
        //创建对象
        Master zhangsan=new Master();
        //创建猫对象
       Cat tom=new Cat();
       //主人喂养猫
        zhangsan.feed(tom);
        //zhangsan.feed(new Cat());
        //创建小狗
        Dog erha=new Dog();
        //主人喂小狗
        zhangsan.feed(erha);
        //zhangsan.feed(new Dog());
    }
}

以上是关于java多态的主要内容,如果未能解决你的问题,请参考以下文章

每个人单核苷酸多态性(SNP)形成的原因是啥?

多态性和动态铸造

Java多态——代码复用性

Java 多态

java多态/重载方法——一个疑难代码引发的讨论

Java 多态