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
  • 示例項目結構 在 Visual Studio 中創建一個 WinForms 應用程式後,項目結構如下所示: MyWinFormsApp/ │ ├───Properties/ │ └───Settings.settings │ ├───bin/ │ ├───Debug/ │ └───Release/ ...
  • [STAThread] 特性用於需要與 COM 組件交互的應用程式,尤其是依賴單線程模型(如 Windows Forms 應用程式)的組件。在 STA 模式下,線程擁有自己的消息迴圈,這對於處理用戶界面和某些 COM 組件是必要的。 [STAThread] static void Main(stri ...
  • 在WinForm中使用全局異常捕獲處理 在WinForm應用程式中,全局異常捕獲是確保程式穩定性的關鍵。通過在Program類的Main方法中設置全局異常處理,可以有效地捕獲並處理未預見的異常,從而避免程式崩潰。 註冊全局異常事件 [STAThread] static void Main() { / ...
  • 前言 給大家推薦一款開源的 Winform 控制項庫,可以幫助我們開發更加美觀、漂亮的 WinForm 界面。 項目介紹 SunnyUI.NET 是一個基於 .NET Framework 4.0+、.NET 6、.NET 7 和 .NET 8 的 WinForm 開源控制項庫,同時也提供了工具類庫、擴展 ...
  • 說明 該文章是屬於OverallAuth2.0系列文章,每周更新一篇該系列文章(從0到1完成系統開發)。 該系統文章,我會儘量說的非常詳細,做到不管新手、老手都能看懂。 說明:OverallAuth2.0 是一個簡單、易懂、功能強大的許可權+可視化流程管理系統。 有興趣的朋友,請關註我吧(*^▽^*) ...
  • 一、下載安裝 1.下載git 必須先下載並安裝git,再TortoiseGit下載安裝 git安裝參考教程:https://blog.csdn.net/mukes/article/details/115693833 2.TortoiseGit下載與安裝 TortoiseGit,Git客戶端,32/6 ...
  • 前言 在項目開發過程中,理解數據結構和演算法如同掌握蓋房子的秘訣。演算法不僅能幫助我們編寫高效、優質的代碼,還能解決項目中遇到的各種難題。 給大家推薦一個支持C#的開源免費、新手友好的數據結構與演算法入門教程:Hello演算法。 項目介紹 《Hello Algo》是一本開源免費、新手友好的數據結構與演算法入門 ...
  • 1.生成單個Proto.bat內容 @rem Copyright 2016, Google Inc. @rem All rights reserved. @rem @rem Redistribution and use in source and binary forms, with or with ...
  • 一:背景 1. 講故事 前段時間有位朋友找到我,說他的窗體程式在客戶這邊出現了卡死,讓我幫忙看下怎麼回事?dump也生成了,既然有dump了那就上 windbg 分析吧。 二:WinDbg 分析 1. 為什麼會卡死 窗體程式的卡死,入口門檻很低,後續往下分析就不一定了,不管怎麼說先用 !clrsta ...
  • 前言 人工智慧時代,人臉識別技術已成為安全驗證、身份識別和用戶交互的關鍵工具。 給大家推薦一款.NET 開源提供了強大的人臉識別 API,工具不僅易於集成,還具備高效處理能力。 本文將介紹一款如何利用這些API,為我們的項目添加智能識別的亮點。 項目介紹 GitHub 上擁有 1.2k 星標的 C# ...