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
  • 1、預覽地址:http://139.155.137.144:9012 2、qq群:801913255 一、前言 隨著網路的發展,企業對於信息系統數據的保密工作愈發重視,不同身份、角色對於數據的訪問許可權都應該大相徑庭。 列如 1、不同登錄人員對一個數據列表的可見度是不一樣的,如數據列、數據行、數據按鈕 ...
  • 前言 上一篇文章寫瞭如何使用RabbitMQ做個簡單的發送郵件項目,然後評論也是比較多,也是準備去學習一下如何確保RabbitMQ的消息可靠性,但是由於時間原因,先來說說設計模式中的簡單工廠模式吧! 在瞭解簡單工廠模式之前,我們要知道C#是一款面向對象的高級程式語言。它有3大特性,封裝、繼承、多態。 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 介紹 Nodify是一個WPF基於節點的編輯器控制項,其中包含一系列節點、連接和連接器組件,旨在簡化構建基於節點的工具的過程 ...
  • 創建一個webapi項目做測試使用。 創建新控制器,搭建一個基礎框架,包括獲取當天日期、wiki的請求地址等 創建一個Http請求幫助類以及方法,用於獲取指定URL的信息 使用http請求訪問指定url,先運行一下,看看返回的內容。內容如圖右邊所示,實際上是一個Json數據。我們主要解析 大事記 部 ...
  • 最近在不少自媒體上看到有關.NET與C#的資訊與評價,感覺大家對.NET與C#還是不太瞭解,尤其是對2016年6月發佈的跨平臺.NET Core 1.0,更是知之甚少。在考慮一番之後,還是決定寫點東西總結一下,也回顧一下.NET的發展歷史。 首先,你沒看錯,.NET是跨平臺的,可以在Windows、 ...
  • Nodify學習 一:介紹與使用 - 可樂_加冰 - 博客園 (cnblogs.com) Nodify學習 二:添加節點 - 可樂_加冰 - 博客園 (cnblogs.com) 添加節點(nodes) 通過上一篇我們已經創建好了編輯器實例現在我們為編輯器添加一個節點 添加model和viewmode ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...
  • 類型檢查和轉換:當你需要檢查對象是否為特定類型,並且希望在同一時間內將其轉換為那個類型時,模式匹配提供了一種更簡潔的方式來完成這一任務,避免了使用傳統的as和is操作符後還需要進行額外的null檢查。 複雜條件邏輯:在處理複雜的條件邏輯時,特別是涉及到多個條件和類型的情況下,使用模式匹配可以使代碼更 ...
  • 在日常開發中,我們經常需要和文件打交道,特別是桌面開發,有時候就會需要載入大批量的文件,而且可能還會存在部分文件缺失的情況,那麼如何才能快速的判斷文件是否存在呢?如果處理不當的,且文件數量比較多的時候,可能會造成卡頓等情況,進而影響程式的使用體驗。今天就以一個簡單的小例子,簡述兩種不同的判斷文件是否... ...
  • 前言 資料庫併發,數據審計和軟刪除一直是數據持久化方面的經典問題。早些時候,這些工作需要手寫複雜的SQL或者通過存儲過程和觸發器實現。手寫複雜SQL對軟體可維護性構成了相當大的挑戰,隨著SQL字數的變多,用到的嵌套和複雜語法增加,可讀性和可維護性的難度是幾何級暴漲。因此如何在實現功能的同時控制這些S ...