Java面向對象(五):OOP三大特性之多態 — final 關鍵字

来源:https://www.cnblogs.com/Kanekiyi/archive/2018/08/20/9508685.html
-Advertisement-
Play Games

一、多態 定義:指允許不同子類的對象對父類同一消息能做出不同的響應。(重寫父類的方法) 即同一消息可以根據發送對象的不同而採用多種不同的行為方式。(發送消息就是函數調用) 1、面向對象的多態的實現前提: (1)要有繼承:類與類之間必須有繼承關係; (2)要有重寫:子類重寫父類的成員方法(可以不重寫, ...


一、多態 

   理解:多態本意是指同一事物在不同的條件會有不同的形態;

映射到Java中可以理解為:同一個父類方法被不同的子類調用,會產生不同的行為(重寫父類的方法);

也可表述為:不同子類的對象對父類同一消息能做出不同的響應(重寫父類的方法)。 即同一消息可以根據發送對象的不同而採用多種不同的行為方式(發送消息就是函數調用)。

1、面向對象的多態的實現前提:

(1)要有繼承:類與類之間必須有繼承關係;

(2)要有重寫:子類重寫父類的成員方法(可以不重寫,但這就失去了多態的意義);

(3)向上轉型:父類引用可以指向任何一個子類的對象。

2、向上轉型(子類自動轉為父類):子類"偽裝"成父類,執行子類的方法;

class Fu { 

  ..... 

class Zi extends Fu {

   .....

      Fu  fu      =   new Zi();

父類  父類引用 =  子類對象 

註:

1、Java指向的兩個時期:編譯器與執行器,編譯期看類型,執行期看對象。

2、多態調用函數的處理過程: 編譯器從父類查找是否有該函數,沒有的話報錯,有的話在執行期執行子類中重寫的同名函數,而不是父類。 

常式:duotai包:ZMS.java ZMSSON.java

3、向下轉型(父類強制轉化為子類):"偽裝"成父類的"子類"還原成真正的子類

Zi zi = (Zi) fu; //類似於強制轉換大範圍到小範圍 

常式:duotai包:ZMS.java ZMSSON.java

ZMS.java

 1 package duoTai;
 2 
 3 public class ZMS {
 4     String name;
 5     int age;
 6 
 7     public void teach() {
 8         
 9         System.out.println("我是父類ZMS教Java");
10     }
11     
12     public void show() {
13         System.out.println(name+age);
14         
15     }
16     
17 }
View Code

ZMSSON.java

 1 package duoTai;
 2 /**
 3  * 創建ZMS子類
 4  * 多態的測試
 5  * 
 6  * */
 7 public class ZMSSON extends ZMS {
 8     
 9     //重寫父類中同名方法
10     public void teach() {
11         
12         System.out.println("我是ZMS子類教文學");
13     //    like();
14     }
15     
16     //子類自己的成員方法
17     public void like() {
18         System.out.println("ZMSSON喜歡踢球");
19         
20     }
21     
22     public static void main(String[] args) {
23     
24         /*
25          * 多態的表示:父類 父類引用名 = 子類對象
26          * 多態調用函數的處理過程: 編譯器從父類查找是否有該函數,沒有的話報錯,
27          *                                                 有的話在執行期執行子類中重寫的同名函數,而不是父類。
28          * 
29          * */
30         ZMS zmsText = new ZMSSON();
31         zmsText.teach();
32         
33         //調用不了父類沒有的方法
34         //zmsText.like();
35     
36         //調用父類的成員變數方法
37         zmsText.name = "zms";
38         zmsText.age = 65;
39         zmsText.show();
40     
41         //
42         ZMSSON zmsSon = (ZMSSON) zmsText;
43         zmsSon.teach();
44         zmsSon.like();
45         
46     }
47     
48 }
View Code

4、多態的好處:

(1)提高了代碼的復用性(繼承)

(2)提高了代碼的擴展性(多態)

5、instanceof 關鍵字:

      boolean b = a instanceof b;

      判斷a類是否屬於另一個b類,是返回true,否則返回false。

 練習:跟據從鍵盤輸入數字不同選擇不同的子類對象,執行不同的響應(重點理解);   

常式:duotai包:Animal.java duoTaiAnimal.java

創建父類:

 1 package duoTai;
 2 
 3 public class Animal {
 4     public String name ;
 5     public int age;
 6     
 7     public void eat() {
 8         System.out.println(name+"動物吃東西");
 9     }
10     
11 }
View Code

創建兩個子類:

 1 package duoTai;
 2 
 3 public class Cat extends Animal{
 4     
 5     //重寫父類方法
 6     public void eat() {
 7         System.out.println("貓吃魚");
 8         
 9     }
10     
11     //寫子類自己的方法
12     public void catchMouse() {
13         System.out.println("抓老鼠");
14     }
15     
16 }
17 
18 
19 // 在另一個java文件中創建
20 package duoTai;
21 
22 public class Dog extends Animal{
23         
24        //重寫父類方法
25         public void eat() {
26             System.out.println("吃狗糧");
27         }
28         
29         //寫子類自己的方法
30         public void kanMen() {
31             System.out.println("狗看門");
32         }
33 }
View Code

  創建測試功能類:  

 1 package duoTai;
 2 
 3 /**
 4  * @author  Kanekiyi
 5  * 理解多態的意義:同一消息(函數)可以根據發出的對象不同而產生不同的行為方式。
 6  *                          Or   不同的對象調用同一個函數能夠產生不同的行為方式。
 7  */
 8 import java.util.Scanner;
 9 
10 public class duoTaiAnimal {
11     
12     @SuppressWarnings("resource")
13     public static void main(String[] args) {
14         
15         System.out.println("請輸入數字1選擇貓,數字2選擇狗");
16         Scanner sc  = new Scanner(System.in);
17 
18         int num = sc.nextInt();
19         Animal animal = new Animal();
20         /*
21          * 向上轉型時,根據指令選擇不同的對象源
22          */
23         if (num == 1) {
24             animal = new Cat();
25         }    else if (num == 2) {
26             animal = new Dog();
27         }    else {
28             System.out.println("輸入數字錯誤請重新輸入數字1或者2");
29         }
30         
31         runAnimal ( animal);
32         
33     }
34     
35     public static  void runAnimal(Animal a) {
36         
37         //根據對象的不同執行子類重寫的eat()方法;
38         a.eat();                                
39         
40         /*
41          * 向下轉型時,註意轉型目標子類類型是否符合
42          * 目的:執行子類中特有的功能
43          *          
44          */
45         
46         if (a instanceof Cat) {
47             Cat cat = (Cat) a;
48             cat.catchMouse();
49             
50         }    else if (a instanceof Dog) {
51             Dog dog = (Dog) a;                                    
52             dog.kanMen();
53             
54         }    else {
55             System.out.println("輸入錯誤,不屬於cat類也不屬於Dog類");
56         }
57         
58     }
59 
60 }
View Code

二、final 關鍵字

2.1 final修飾類

  final修飾的類不能被繼承;

2.2 final修飾變數

final 變數能被顯式地初始化並且只能初始化一次。被聲明為 final 的對象的引用不能指向不同的對象,但是 final 對象里的數據可以被改變。也就是說 final 對象的引用不能改變,但是裡面的值可以改變。(存疑)。

final與static一起修飾成員變數構成常量,聲明的時候常量名全部大寫,可以直接通過類名訪問。

常式:

 1 package Fianal;
 2 
 3 
 4 //public class Final1 extends Final0{        final修飾的類不能夠被繼承
 5 public class Final1 {
 6     
 7     int IDCard ;
 8      //final修飾的成員變數聲明時初始化且有且只初始化一次。
 9     final int IDCardNum =314;         
10     final int IDCardNum1;                                 
11 
12     static final String IDCARD= "36452345245X";
13     
14     //通過構造函數給final修飾的成員變數初始化
15     public Final1() {
16         super();
17         IDCardNum1 =314; 
18         
19     }
20 
21     public final void textMath() {
22         
23         System.out.println("我是Final1類的final方法");
24     }
25     
26      
27 }
View Code

2.3 final 修飾方法

final 修飾成員方法,可以被子類繼承,但是不能被重寫;

註:

1、final 修飾的成員變數初始化的兩種方式:

1) 聲明時就初始化;

2)通過構造函數初始化。

且只初始化一次,初始化後就不能修改。

2、final 修飾的變數為常量時,在載入時系統會將變數替換為其所表示的常量。

常式:

 1 package Fianal;
 2 
 3 public class Final2 extends Final1 {
 4     
 5     //父類final修飾的成員方法不能重寫,只能調用
 6     //public final void textMath() {}
 7     
 8     public static void main(String[] args) {
 9         Final2 textFinal = new Final2();
10         textFinal.IDCard = 2;
11         
12         //final修飾的變數在聲明時就初始化且只能初始化一次,只能被調用不能被修改
13         //textFinal.IDCardNum = 3;
14         System.out.println("普通成員變數IDCard:"+textFinal.IDCard);
15         System.out.println("final修飾的成員變數IDCardNum:"+textFinal.IDCardNum);
16         //System.out.println("final和static修飾的成員變數IDCARD:"+textFinal.IDCARD);
17         //常量可以直接調用或類名調用
18         System.out.println("final和static修飾的成員變數IDCARD:"+Final1.IDCARD);
19         System.out.println("final和static修飾的成員變數IDCARD:"+IDCARD);
20 
21         textFinal.textMath();
22         
23     }
24     
25 }
View Code

 

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 運算符描述 ** 指數 (最高優先順序) ~ + - 按位翻轉, 一元加號和減號 (最後兩個的方法名為 +@ 和 -@) * / % // 乘,除,取模和取整除 + - 加法減法 >> << 右移,左移運算符 & 位 'AND' ^ | 位運算符 <= < > >= 比較運算符 <> == != 等於 ...
  • BigDecimal 類的使用 1、使用 BigDecimal 的原因   由於需要計算金額,所有需要高精度計算,所有需要使用 BigDecimal 類。 BigDecimal能夠精確的表示一個小數,常用於商業和科學計算;float,double不能精確的表示一個小數。 2、常用 ...
  • new delete初探 1,new有2個作用 開闢記憶體空間。 調用構造函數。 2,delete也有2個作用 釋放記憶體空間 調用析構函數。 如果用new開闢一個類的對象的數組,這個類里必須有預設(沒有參數的構造函數,或者有預設值的參數的構造函數)的構造函數。 釋放數組時,必須加[]。delete [ ...
  • 開始了,繼續說!字元串替換,就是預留著空間,後邊再定義要填上什麼,這種叫字元串格式化,其有兩種方法: % 和 format %s 就是一個占位符,這個占位符可以被其它的字元串代替 >>> "I like %s" % "python" 'I like python' string.format()的格 ...
  • 你是一個專業的小偷,計劃偷竊沿街的房屋。每間房內都藏有一定的現金,影響你偷竊的唯一制約因素就是相鄰的房屋裝有相互連通的防盜系統,如果兩間相鄰的房屋在同一晚上被小偷闖入,系統會自動報警。 給定一個代表每個房屋存放金額的非負整數數組,計算你在不觸動警報裝置的情況下,能夠偷竊到的最高金額。 示例 1: 輸 ...
  • 目錄: 一、pickle模塊 二、課時31課後習題及答案 ****************** 一、pickle模塊 ****************** Python提供了一個標準模塊,使用這個模塊,就可以輕鬆地將列表、字典這類複雜類型存儲為文件了。這個模塊就是pickle模塊。 它幾乎可以把所有 ...
  • 序言 這個是從抖音上學來的,一開始刷抖音,遇到不少字元串跳舞的視頻,因此來實踐一下 主要分為三個部分 1. 靜態圖片轉靜態圖片 2. gif轉gif 3. 視頻轉視頻 靜態圖片轉靜態圖片 其實原理很簡單,讀取圖片的像素,新建一張大小一樣的圖片,根據原圖像素的灰度,決定是不是要顯示出來,併在新圖相應的 ...
  • 思路: 不要去考慮刪除的字眼,要考慮如何進行保存非 x 的值 這裡提供兩種解法,殊途同歸: 1.將其中非 x 的元素統計並保存 2.統計為 x 的元素個數,並將非 x 的元素保存 註意事項: 註意這裡代碼由於使用了引用(&),只能在 C++ 中編譯通過 使用指針的時候一定要註意開闢空間,否則之後可能 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...