day11-面向對象02

来源:https://www.cnblogs.com/liyuelian/archive/2022/07/31/16538552.html
-Advertisement-
Play Games

面向對象02 7.==繼承== 繼承的本質是對某一批類的抽象,從而實現對現實世界更好地建模 extends的意思是“擴展”。子類是父類的擴展。 Java類中只有單繼承,沒有多繼承!(一個兒子只能有一個爸爸,一個爸爸可以有多個兒子) 繼承是類和類之間的一種關係。除此之外,類和類之間的關係還有依賴、組合 ...


面向對象02

7.繼承

  • 繼承的本質是對某一批類的抽象,從而實現對現實世界更好地建模
  • extends的意思是“擴展”。子類是父類的擴展。
  • Java類中只有單繼承,沒有多繼承!(一個兒子只能有一個爸爸,一個爸爸可以有多個兒子)
  • 繼承是類和類之間的一種關係。除此之外,類和類之間的關係還有依賴、組合、聚合等。
  • 繼承關係的兩個類,一個為子類(派生類),一個為父類(基類)。子類繼承父類,使用關鍵字extends表示
  • 子類和父類之間,從意義上講應該具有“is a”的關係
  • object類
  • super
  • 方法重寫

子類繼承了父類,就會有父類的全部方法!(私有的東西無法被繼承)

例子1:

package li.oop.demo05;

//父類:Person 人
public class Person {

    //public
    //protected
    //default
    //private
    public int money = 10_0000_0000;

    public void say(){
        System.out.println("說了一句話");
    }

    public int getMoney() {
        return money;
    }

    public void setMoney(int money) {
        this.money = money;
    }
}
package li.oop.demo05;
//學生 is 人
//派生類(子類),子類繼承了父類,就會有父類的全部方法
public class Student extends Person{

}
package li.oop;

import li.oop.demo05.Student;

public class Application {
    public static void main(String[] args) {
        Student student = new Student();
        student.say();//說了一句話
        System.out.println(student.money);// 1000000000
    }

}
image-20220729214339154

7.1Object類

在Java中,所有的類都預設直接或者間接繼承Object類

7.2Super關鍵字

  • super. 大部分情況下是可以省略的。
    當父中類有,子類中又有,如果想在子中訪問“父的特征”,super. 不能省略。
    在父和子中有同名的屬性,或者說有相同的方法,如果此時想在子類中訪問父中的數據,必須使用“super.”加以區分。

    • super.屬性名 --->訪問父類的屬性

    • super.方法名(實參) --->訪問父類的方法

    • super(實參) ---->調用父類的構造方法

  • 子類繼承父類,子類的構造方法必須調用super()即父類的構造方法,而且必須放在構造方法的第一行。

    子類構造方法第一行都有調用父類無參的構造方法,如果你不顯示地寫出了,系統會自己加上;

    但是如果你的父類重載了一個或多個構造方法,系統將不再預設加上無參的構造方法,必須自己加上。

  1. super調用父類的構造方法,必須在構造方法中的第一行
  2. super必須只能出現在子類的方法或者構造方法中
  3. super和this不能同時調用構造方法
  4. super&&this
    • 代表的對象不同:
      • this:代表本身調用者這個對象
      • 代表當前類的父類對象的引用
    • 前提:
      • this:沒有繼承也可以使用
      • super:只能在繼承條件下才可以使用
    • 構造方法的區別:
      • this(); 本類的構造
      • super(); 父類的構造

7.3方法重寫

例子1:

package li.oop.demo05;
//重寫都是方法的重寫,和屬性無關
public class B {
    public static void test(){
        System.out.println("B==>test");
    }
}
package li.oop.demo05;
public class A extends B{

    public static void test(){
        System.out.println("A==>test");
    }
}
package li.oop;

import li.oop.demo05.A;
import li.oop.demo05.B;

public class Application {
    public static void main(String[] args) {
       //靜態方法:方法的調用只和左邊定義的類型有關
       A a = new A();
       a.test();//調用的是A類方法

       //父類的引用指向了子類
       B b = new A();
       b.test();//調用的是B類方法

    }
}
image-20220730150501414

靜態方法:方法的調用只和左邊定義的類型有關

例子2:

package li.oop.demo05;
//重寫都是方法的重寫,和屬性無關
public class B {
    public  void test(){
        System.out.println("B==>test");
    }
}
package li.oop.demo05;

public class A extends B{
    //Override  重寫
    @Override // 註解:有功能的註解!
    public void test(){
        System.out.println("A==>test");
    }
}
package li.oop;
import li.oop.demo05.A;
import li.oop.demo05.B;

//靜態方法和非靜態方法區別很大!
//靜態方法:方法的調用只和左邊定義的類型有關
//非靜態:重寫
public class Application {
    public static void main(String[] args) {

       A a = new A();
       a.test();

       //父類的引用指向了子類
       B b = new A();//子類重寫了父類的方法
       b.test();
    }
}
image-20220730151534644

總結:

重寫 :子類的方法和父類的方法必須要一致,方法體不同

-- 重寫前提:需要有繼承關係,子類重寫父類的方法

  1. 方法名必須相同
  2. 參數列表必須相同
  3. 修飾符:範圍可擴大,但不能縮小:public>protected>default>private
  4. 拋出的異常:範圍可以被縮小,但不能擴大。例如:ClassNotFoundException(範圍小)-->Exception(範圍大)

為什麼需要重寫?:父類的功能,子類不一定需要,或者不一定滿足!

快捷鍵:Alt+insert:Override;

8.多態

8.1多態的定義和使用

  • 即同一方法可以根據發送對象的不同而採取多種不同的行為方式

  • 一個對象的實際類型是確定的,但可以指向對象的引用類型有很多

    這裡的引用一般指父類或者有關係的類

  • 多態存在的條件:

    • 有繼承關係
    • 子類重寫父類方法
    • 父類引用指向子類對象
  • 註意:多態是方法的多態,屬性沒有多態性

  • instanceof (類型轉換)引用類型

例子1:

package li.oop.demo06;

public class Person {
    public void run(){
        System.out.println("run");
    }
}
package li.oop.demo06;

public class Student extends Person{

}
package li.oop;

import li.oop.demo06.Person;
import li.oop.demo06.Student;

public class Application {
    public static void main(String[] args) {

        //一個對象的實際類型是確定的
        //new Student();
        //new Person();

        //但是可以指向的引用類型就不確定了
        Student s1 = new Student();
        Person s2 = new Student();//父類的引用指向子類
        Object s3 = new Student();//父類的引用指向子類

        s2.run();//這裡雖然new的是Student,但是是它依舊走的是父類的方法,因為子類繼承了父類的全部方法
    }
}
image-20220730154506673

這裡的 s2 雖然new的是Student,但是是s2.run() 依舊走的是父類的方法,因為子類繼承了父類的全部方法

例子2

package li.oop.demo06;

public class Person {
    public void run(){
        System.out.println("run");
    }
}
package li.oop.demo06;

public class Student extends Person{
    @Override
    public void run() {
        System.out.println("son");
    }

    public void eat(){
        System.out.println("eat");
    }
}
package li.oop;

import li.oop.demo06.Person;
import li.oop.demo06.Student;

public class Application {
    public static void main(String[] args) {

        //一個對象的實際類型是確定的
        //new Student();
        //new Person();
        //但是可以指向的引用類型就不確定了

        //Sudent能調用的方法都是自己的或者繼承父類的
        Student s1 = new Student();

        //Person父類型:可以指向子類,但是不能調用子類獨有的方法
        Person s2 = new Student();//父類的引用指向子類
        Object s3 = new Student();//父類的引用指向子類

        s2.run();//子類重寫了父類的方法,執行子類的方法
        s1.run();

        //s2.eat 不能調用  s2為Person父類型:可以指向子類,但是不能調用子類獨有的方法
        ((Student) s2).eat();//強制類型轉換後才可以使用
        //對象能夠執行的方法主要看對象左邊的類型和右邊關係不大
    }

}

對象能夠執行的方法主要看對象左邊的類型和右邊關係不大

//Person父類型:可以指向子類,但是不能調用子類獨有的方法
Person s2 = new Student();//父類的引用指向子類

//子類Sudent能調用的方法都是自己的或者繼承父類的
Student s1 = new Student();

image-20220730155646033

多態註意事項:

  • 多態是方法的多態,屬性沒有多態
  • 父類和子類,有聯繫
  • 多態存在的必要條件:
    • 有繼承關係
    • 方法需要重寫
      • 不能重寫的方法:
        • 1.static 方法,屬於類,它不屬於實例
        • final 常量
        • private 方法
    • 父類的引用指向子類對象

8.2instanceof

instanceof(類型轉換)引用類型,判斷一個對象是什麼類型

例子1:

package li.oop.demo06;

public class Person {
    public void run(){
        System.out.println("run");
    }
}
package li.oop.demo06;
public class Student extends Person{
}
package li.oop.demo06;
public class Teacher extends Person{
}
package li.oop;

import li.oop.demo06.Person;
import li.oop.demo06.Student;
import li.oop.demo06.Teacher;

public class Application {
    public static void main(String[] args) {

        //Object > Person > Student
        //Object > Person > Teacher
        //Object > String

        Object object = new Student();
        System.out.println(object instanceof Student);//true
        System.out.println(object instanceof Person);//true
        System.out.println(object instanceof Object);//true
        System.out.println(object instanceof Teacher);//false
        System.out.println(object instanceof String);//false

        System.out.println("==============");

        Person person = new Student();
        System.out.println(person instanceof Student);//true
        System.out.println(person instanceof Person);//true
        System.out.println(person instanceof Object);//true
        System.out.println(person instanceof Teacher);//false
       // 編譯就報錯了 System.out.println(person instanceof String);

        System.out.println("==============");

        Student student = new Student();
        System.out.println(student instanceof Student);//true
        System.out.println(student instanceof Person);//true
        System.out.println(student instanceof Object);//true
        // 編譯就報錯了 System.out.println(student instanceof Teacher);
        //編譯就報錯了 System.out.println(student instanceof String);

    }
}

總結:

System.out.println(X instanceof Y);

能不能編譯通過,取決於X與Y之間是否存在直系繼承關係

image-20220730170759125

8.3類的類型轉換

  • 基本類型轉換
    • 高容量轉換成低容量:強制類型轉換
    • 低容量轉換成高容量:自動類型轉換
  • 類之間的轉化:父類代表高的,子類代表低的
    • 父轉子:強制轉換
    • 子轉父:自動轉換

例子:

package li.oop.demo06;

public class Person {
    
}
package li.oop.demo06;

public class Student extends Person{
    public void go(){
        System.out.println("go");
    }
}
package li.oop;
import li.oop.demo06.Person;
import li.oop.demo06.Student;

public class Application {
    public static void main(String[] args) {

        /*類型之間的轉換:
         1.基本類型轉換-->高容量轉換成低容量:強制類型轉換
                       低容量轉換成高容量:自動類型轉換
         2.類之間的轉化:父類代表高的,子類代表低的
         */

        //高   <--- ---- ---     低
        Person student = new Student();

        //這裡只有在子類Student類中才有go()方法,
        // 而student對象是Person類型的,因此不能直接調用,需要強制類型轉換成子類類型才能使用go()方法
        //高   --- ---- --- >    低
        ((Student) student).go();//go

        //或者
        Person obj = new Student();
        Student student1 = (Student) obj;//強制轉換
        student1.go();//go


        /*
        子類轉換成父類可能會丟失自己本來的一些方法
         */
        Student student2 = new Student();
        student2.go();//go
        Person person = student2;//自動轉換 低-->高
       //這裡的 person對象就不能使用原本子類的go()方法了

    }
}
image-20220730172902824

總結:

  1. 父類的引用指向子類的對象(子類的引用不能指向父類的對象)

  2. 把子類轉換為父類,向上轉型(自動類型轉換)

  3. 把父類轉換為子類,向下轉型(強制轉換)

    基本數據類型的強制轉換可能會丟失精度,類的強制轉換可能會丟失一些方法

  4. 為什麼會存在類的類型轉換?方便方法的調用,減少重覆代碼,更簡潔

9.static關鍵字詳解

9.1靜態變數和靜態方法

例子1:靜態變數儘量使用類名來訪問

package li.oop.demo07;

//static
public class Student {
    private static int age;//靜態的變數
    private double score;//非靜態的變數

    public static void main(String[] args) {
        Student s1 = new Student();

        //1.靜態變數儘量使用類名來訪問
        //通過類來使用
        System.out.println(Student.age);//0
        //通過對象來使用
        System.out.println(s1.age);//0
        System.out.println(s1.score);//0.0

    }

}

例子2:靜態方法

  • 調用非靜態方法需要通過實例對象來調用

  • 調用靜態方法可以直接通過類調用,如果如果靜態方法和main方法在同一個類中,甚至可以直接調用

  • 非靜態方法可以去調用靜態方法里的所有東西,而靜態方法不能調非靜態方法

package li.oop.demo07;

//static
public class Student {
    private static int age;//靜態的變數
    private double score;//非靜態的變數


    public  void run(){
        System.out.println("run");
    }
    public static void go(){
        System.out.println("go");
    }

    public static void main(String[] args) {
        
       //2.靜態方法
        //調用非靜態方法需要通過實例對象來調用
        Student s2 = new Student();
        s2.run();

        //調用靜態方法可以直接通過類調用,如果如果靜態方法和main方法在同一個類中,甚至可以直接調用
        Student.go();
        go();
        
         //3.非靜態方法可以去調用靜態方法里的所有東西,而靜態方法不能調非靜態方法
        //比如在靜態方法main()中不能直接調用非靜態方法run()

    }
}

9.2靜態代碼塊

package li.oop.demo07;

public class Person {
    {
        //代碼塊(匿名代碼塊)
    }

    static{
        //靜態代碼塊
    }

}
  • 如上所示,在類中用大括弧括起來的一段沒有名字的代碼塊稱為匿名代碼塊。在括弧前加上static關鍵字的代碼塊稱為靜態代碼塊。

  • 匿名代碼塊沒有名字,程式在執行時並不能主動去調用這些模塊。在創建對象的時候匿名代碼塊自動創建,並且在構造器之前

  • 靜態代碼塊是類載入的同時就直接執行,永久只執行一次

例子:匿名代碼塊、靜態代碼塊、構造方法的載入順序

package li.oop.demo07;

public class Person {
    {
        System.out.println("匿名代碼塊");//代碼塊(匿名代碼塊)
    }

    static{
        System.out.println("靜態代碼塊");//靜態代碼塊
    }

    public Person() {
        System.out.println("構造方法");
    }

    public static void main(String[] args) {
        
        System.out.println("==========111");
        Person person1 = new Person();

        System.out.println("==========222");
        Person person2 = new Person();

    }
}
image-20220730193306924

載入順序:

靜態代碼塊>匿名代碼塊>構造函數

靜態代碼塊在person1實例化前就執行了,靜態代碼塊是在類載入的同時就執行了,並且只執行一次

9.3靜態導入包

package li.oop.demo07;

//靜態導入包~
import static java.lang.Math.random;
import static java.lang.Math.PI;

public class Test {
    public static void main(String[] args) {
        System.out.println(random());
        System.out.println(PI);
    }
}
image-20220730194156371

PS:被final修飾的類不能被其他類繼承

image-20220730194358164 image-20220730194335674
您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • Javascript基礎Day1 1、js的書寫位置: 行內式(不推薦): 情況1: <div onclick="alert(123)">hello</div> <p onclick="alert(123)">hello</p> 情況2: <a href="javascript:alert(4567 ...
  • 1.安裝nodejs(建議最新版本) 下載地址:下載 | Node.js 中文網 在安裝的過程中建議不要裝在C盤,安裝完成配置環境變數,並且建議講緩存路徑更改。 安裝完成後通過查看nodejs版本和npm版本,在終端輸入 npm --version 和node --version,如下圖所示: 2. ...
  • BOM 原生對象:成為js中的內置對象,就是由 js 中的構造函數創建的對象就被稱為原生對象:Object、Number、Array、Date、String。。。。 宿主對象:web運行環境,也就是windows操作系統和瀏覽器這些被稱為宿主,有這些宿主提供的對象,就叫宿主對象。 *BOM:瀏覽器對 ...
  • JavaScript基礎 1、JavaScript概述 W3C標準:網頁主要由三部分組成 HTML:用來製作網頁基礎內容和基本結構 CSS:用來網頁樣式美化效果 JavaScript:用來製作數據驗證,和用戶交互 JavaScript概念 JavaScript是一門跨平臺、面向對象的腳本語言,運行在 ...
  • CSS 基礎 1、CSS介紹 CSS概念 Cascading Style Sheet層疊樣式表,通過不同的樣式可以讓網頁更漂亮,樣式也可疊加得到最終的效果。CSS用於渲染html元素進行樣式控制的語言 CSS作用 網頁美化 HTML與CSS的區別 HTML:網頁結構的創建 CSS:網頁美化 2、CS ...
  • HTML基礎 1、HTML的概念和作用 概念 HTML(Hyper Text Markup Language):超文本標記語言 超文本:不僅包含普通文本,還可以包含圖片、視頻、音頻、超鏈接、表格等內容 標記語言:由標簽構成的語言 HTML的作用 編寫網頁 2、W3C標準 網頁主要由三部分組成 HTM ...
  • 前言 在分散式架構中項目部署在多台不同的伺服器上,每台伺服器都有自己的crontab任務很容易造成任務執行衝突且不易於定時任務的統一管理; 此時微服務中就需要1個定時任務任務調度中心,對微服務架構中每1台伺服器里的定時任務,進行集中管理,統一定時任務的執行頻率; 一、xxl-job簡介 xxl-jo ...
  • 23 枚舉 枚舉是一組符號名稱(枚舉成員)的集合,枚舉成員應該是唯一的、不可變的。 23.1 使用普通類實現枚舉類 class basicWeek(): SUN=0 MON=1 TUE=2 WED=3 THU=4 FRI=5 SAT=6 # 獲取值 print(basicWeek.SUN) # 0 ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...