首頁  >  文章  >  Java  >  一文掌握JAVA 物件導向之多態

一文掌握JAVA 物件導向之多態

WBOY
WBOY轉載
2022-06-15 11:48:111911瀏覽

本篇文章為大家帶來了關於java的相關知識,其中主要介紹了關於多態的相關問題,多態是物件導向程式設計的重要特徵,指向同一個實體同時具有多種形式,指的是對象的多種形態,下面一起來看一下,希望對大家有幫助。

一文掌握JAVA 物件導向之多態

推薦學習:《java影片教學

1. 概念

多態是物件導向程序設計(OOP)的一個重要特徵,指同一個實體同時具有多種形式,即同一個對象,在不同時刻,代表的對像不一樣,指的是對象的多種形態。

可以把不同的子類別物件當作父類別來看,進而屏蔽不同子類別物件之間的差異,寫出通用的程式碼,做出通用的編程,統一呼叫標準。

例如,你的女盆友讓你買點水果回來,不管買回來的是蘋果還是西瓜,只要是水果就行,這個就是生活中多態的體現

#再比如,小貓、小狗、小豬我們可以把他們都歸納成小動物,每種小動物都需要吃東西,所以我們可以統一設置他們都必須吃,但是每種小動物的習性不一樣,那這個就可以設定成小動物自己特有的功能,多型物件只能呼叫父類別中定義子類別中重寫的功能,並不能呼叫子類別的特有功能,這樣就實現了程式碼的統一

2 . 特點

  1. 多態的前提1:是繼承
  2. 多態的前提2:要有方法的重寫
  3. 父類別引用指向子類物件,如:Animal a = new Cat();
  4. 多態中,編譯看左邊,運行看右邊
    一文掌握JAVA 物件導向之多態

3. 練習:多態入門案例

建立套件: cn.tedu.oop
建立類別: TestDemo.java

package cn.tedu.oop2;/*本类用作多态的入门案例*/public class TestDemo {
    public static void main(String[] args) {
        //6.创建“纯纯的”对象用于测试
        Animal a = new Animal();
        Cat c = new Cat();
        Dog d = new Dog();
        a.eat();//小动物Animal吃啥都行~调用的是父类自己的功能
        c.eat();//小猫爱吃小鱼干~调用的是子类重写后的功能
        d.eat();//小狗爱吃肉骨头~调用的是子类重写后的功能
        /*2.父类对象不可以使用子类的特有功能*/
        //a.jump();//报错,Animal类里并没有这个方法
        //a.run();//报错,Animal类里并没有这个方法
        c.jump();//小猫Cat跳的老高啦~,子类可以调用自己的功能
        d.run();//小狗Dog跑的老快啦~,子类可以调用自己的功能

        //7.创建多态对象进行测试
        /*3.口诀1:父类引用指向子类对象
        * 解释:创建出来的子类对象的地址值,交给父类类型的引用类型变量来保存*/
        Animal a2 = new Cat();//Cat类对象的地址值交给父类型变量a2来保存
        Animal a3 = new Dog();//Dog类对象的地址值交给父类型变量a3来保存
        //8.测试多态对象
        /*4.口诀2:编译看左边,运行看右边
        * 解释:必须要在父类定义这个方法,才能通过编译,把多态对象看作是父类类型
        *      必须要在子类重写这个方法,才能满足多态,实际干活的是子类*/
        a2.eat();//小猫爱吃小鱼干~,多态对象使用的是父类的定义,子类的方法体
    }}/*1.多态的前提:继承+重写*///1.创建父类class Animal{
    //3.创建父类的普通方法
    public void eat(){
        System.out.println("小动物Animal吃啥都行~");
    }}//2.1创建子类1class Cat extends Animal{
    //4.1添加重写的方法
    public void eat(){
        System.out.println("小猫爱吃小鱼干~");
    }
    //5.1添加子类的特有功能
    public void jump(){
        System.out.println("小猫Cat跳的老高啦~");
    }}//2.2创建子类2class Dog extends Animal{
    //4.2添加重写的方法
    @Override
    public void eat(){
        System.out.println("小狗爱吃肉骨头~");
    }
    //5.2添加子类的特有功能
    public void run(){
        System.out.println("小狗Dog跑的老快啦~");
    }}

4. 多態的好處

    ##多態可以讓我們不用關心某個物件到底具體是什麼類型,就可以使用該物件的某些方法
  1. 提高了程式的可擴展性和可維護性
5.多態的使用

前提:多型物件把自己看做是父類別型別

    成員變數: 使用的是父類別的
  1. 成員方法:由於存在重寫現象,所以使用的是子類別的
  2. 靜態成員: 隨著類別的載入而載入,誰呼叫就回傳誰的
6. 練習:多態成員使用測試

建立套件: cn.tedu.oop

建立類別: TestDemo2.java

package cn.tedu.oop2;/*本类用于测试多态成员的使用情况*/public class TestDemo2 {
    public static void main(String[] args) {
        //7.创建纯纯的子类对象
        Dog2 d = new Dog2();
        System.out.println(d.sum);//20,子类自己的属性
        d.eat();//小狗爱吃肉包子,子类自己的方法

        //8.创建多态对象
        /*口诀1:父类引用指向子类对象*/
        /*口诀2:编译(保存)看左边,运行(效果)看右边*/
        Animal2 a = new Dog2();
        /*多态中,成员变量使用的是父类的*/
        System.out.println(a.sum);//10
        /*多态中,方法的声明使用的是父类的,方法体使用的是子类的*/
        a.eat();//小狗爱吃肉包子
        /*多态中,调用的静态方法是父类的,因为多态对象把自己看作是父类类型
        * 直接使用父类中的静态资源*/
        a.play();//没有提示,玩啥都行~
        Animal2.play();
    }}//1.创建父类class Animal2{
    //3.创建父类的成员变量
    int sum = 10;
    //4.创建父类的普通方法
    public void eat(){
        System.out.println("吃啥都行~");
    }
    //9.1定义父类的静态方法play
    public static void play(){
        System.out.println("玩啥都行~");
    }}//2.创建子类class Dog2 extends Animal2{
    //5.定义子类的成员变量
    int sum = 20;
    //6.重写父类的方法
    @Override
    public void eat(){
        System.out.println("小狗爱吃肉包子");
    }
    //9.2创建子类的静态方法play
    //@Override
    /*这不是一个重写的方法,只是恰巧在两个类中出现了一模一样的两个静态方法
    * 静态方法属于类资源,只有一份,不存在重写的现象
    * 在哪个类里定义,就作为哪个类的资源使用*/
    public static void play(){
        System.out.println("小狗喜欢玩皮球~");
    }}
7 拓展

##7.1 設計汽車綜合案例

建立套件: cn.tedu.oopexec

建立類別: DesignCar.java

package cn.tedu.oop2;/*本类用于完成汽车设计案例*/public class DesignCar {
    public static void main(String[] args) {
        //9.创建一个纯纯的父类对象进行测试
        Car c = new Car();
        System.out.println(c.getColor());//null
        c.start();
        c.stop();
        //c.swim();//报错,父类对象不可以调用子类的特有功能

        //10.创建纯纯的子类对象做测试
        BMW b = new BMW();
        System.out.println(b.color);//五彩斑斓的黑
        System.out.println(b.getColor());//null
        b.start();//都让开,我的车要起飞啦~
        b.stop();//唉呀妈呀熄火了~

        //11.创建多态对象进行测试
        Car c2 = new TSL();
        //System.out.println(c2.color);
        System.out.println(c2.getColor());
        c2.stop();
        c2.start();
        //c2.swim();
    }}//1.通过分析,抽象形成一个汽车类class Car{
    //2.定义并封装汽车类的属性--成员变量
    private String brand;//品牌
    private String color;//颜色
    private int id;//编号
    private double price;//价格

    //3.定义功能
    public void start(){
        System.out.println("我的小车车启动啦~");
    }
    public void stop(){
        System.out.println("唉呀妈呀熄火了~");
    }

    public String getBrand() {
        return brand;
    }

    public void setBrand(String brand) {
        this.brand = brand;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        this.color = color;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public double getPrice() {
        return price;
    }

    public void setPrice(double price) {
        this.price = price;
    }}//4.创建子类class BMW extends Car{
    String color = "五彩斑斓的黑";
    //5.重写父类的方法
    @Override
    public void start(){
        System.out.println("都让开,我的车要起飞啦~");
    }}//6.创建子类2class TSL extends Car{
    //7.重写父类的方法
    @Override
    public void stop(){
        System.out.println("唉呀妈,怎么停不下来呢");
    }
    //8.添加子类的特有功能
    public void swim(){
        System.out.println("没想到吧,我还是个潜水艇");
    }}

7.2 多態為了統一呼叫標準

#
package cn.tedu.oop2;public class TestFruit {
    public static void main(String[] args) {
        Fruit f = new Fruit();
        Apple a = new Apple();
        Orange o = new Orange();
        get(f);
        get(a);
        get(o);
    }
    //只需要创建一个方法,就可以执行截然不同的效果
    //忽略子类对象的差异统一看作父类类型
    public static void get(Fruit f){
        f.clean();
    }}class Fruit{
    public void clean(){
        System.out.println("水果要洗洗再吃");
    }}class Apple extends Fruit{
    @Override
    public void clean(){
        System.out.println("苹果需要削皮");
    }}class Orange extends Fruit{
    @Override
    public void clean(){
        System.out.println("橙子需要剥皮");
    }}

7.3 靜態變數與實例變數的差異

在語法定義上的差異:靜態變數前要加static關鍵字,而實例變數前則不加。

在程式執行時的差異:實例變數屬於某個對象的屬性,必須建立了實例對象,其中的實例變數才會被指派空間,才能使用這個實例變數。靜態變數不屬於某個實例對象,而是屬於類,所以也稱為類變量,只要程式載入了類的字節碼,不用創建任何實例對象,靜態變數就會被分配空間,靜態變數就可以被使用了。總之,實例變數必須在建立物件後才可以透過這個物件來使用,靜態變數則可以直接使用類別名稱來引用。


7.4 向轉型和向下轉型

在JAVA中,繼承是一個重要的特徵,透過extends關鍵字,子類別可以復用父類別的功能,如果父類別不能滿足目前子類別的需求,則子類別可以重寫父類別中的方法來擴展。

那麼在這個過程中就存在著多態的應用。存在著兩種轉型方式,分別是:向上轉型和向下轉型。

向上轉型:可以把不同的子類別物件都當作父類別來看,進而屏蔽不同子類別物件之間的差異,寫出通用的程式碼,做出通用的編程,統一調用標準。
例如:父類別Parent,子類別Child
父類別的參考指向子類別物件:Parent p=new Child();
說明:向轉型時,子類別物件當成父類別對象,只能呼叫父類別的功能,如果子類別重寫了父類別中宣告過的方法,方法體執行的就是子類別重過後的功能。但此時物件是把自己看做是父類別類型的,所以其他資源使用的還是父類型的。
例如:花木蘭替父從軍,大家都把花木蘭看做她爸,但是實際從軍的是花木蘭,而且,花木蘭只能做她爸能做的事,在軍營裡是不可以化妝的。

向下轉型(較少):子類別的引用的指向子類別對象,過程中必須要採取到強制轉型。這個是之前向上造型過的子類別物件仍然想執行子類別的獨特功能,所以需要重新恢復成子類別物件
Parent p = new Child();//向上轉型,此時,p是Parent類型
Child c = (Child)p;//此時,把Parent類型的p轉成小類型Child
其實,相當於創建了一個子類別物件一樣,可以用父類別的,也可以用自己的
說明:向下轉型時,是為了方便使用子類別的特殊方法,也就是說當子類別方法做了功能拓展,就可以直接使用子類別功能。
例如:花木蘭打仗結束,就不需要再看做是她爸了,就可以」對鏡貼花黃」了

推薦學習:《java影片教學

以上是一文掌握JAVA 物件導向之多態的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除