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
  • 下麵是一個標準的IDistributedCache用例: public class SomeService(IDistributedCache cache) { public async Task<SomeInformation> GetSomeInformationAsync (string na ...
  • 這個庫提供了在啟動期間實例化已註冊的單例,而不是在首次使用它時實例化。 單例通常在首次使用時創建,這可能會導致響應傳入請求的延遲高於平時。在註冊時創建實例有助於防止第一次Request請求的SLA 以往我們要在註冊的時候實例單例可能會這樣寫: //註冊: services.AddSingleton< ...
  • 最近公司的很多項目都要改單點登錄了,不過大部分都還沒敲定,目前立刻要做的就只有一個比較老的項目 先改一個試試手,主要目標就是最短最快實現功能 首先因為要保留原登錄方式,所以頁面上的改動就是在原來登錄頁面下加一個SSO登錄入口 用超鏈接寫的入口,頁面改造後如下圖: 其中超鏈接的 href="Staff ...
  • Like運算符很好用,特別是它所提供的其中*、?這兩種通配符,在Windows文件系統和各類項目中運用非常廣泛。 但Like運算符僅在VB中支持,在C#中,如何實現呢? 以下是關於LikeString的四種實現方式,其中第四種為Regex正則表達式實現,且在.NET Standard 2.0及以上平... ...
  • 一:背景 1. 講故事 前些天有位朋友找到我,說他們的程式記憶體會偶發性暴漲,自己分析了下是非托管記憶體問題,讓我幫忙看下怎麼回事?哈哈,看到這個dump我還是非常有興趣的,居然還有這種游戲幣自助機類型的程式,下次去大玩家看看他們出幣的機器後端是不是C#寫的?由於dump是linux上的程式,剛好win ...
  • 前言 大家好,我是老馬。很高興遇到你。 我們為 java 開發者實現了 java 版本的 nginx https://github.com/houbb/nginx4j 如果你想知道 servlet 如何處理的,可以參考我的另一個項目: 手寫從零實現簡易版 tomcat minicat 手寫 ngin ...
  • 上一次的介紹,主要圍繞如何統一去捕獲異常,以及為每一種異常添加自己的Mapper實現,並且我們知道,當在ExceptionMapper中返回非200的Response,不支持application/json的響應類型,而是寫死的text/plain類型。 Filter為二方包異常手動捕獲 參考:ht ...
  • 大家好,我是R哥。 今天分享一個爽飛了的面試輔導 case: 這個杭州兄弟空窗期 1 個月+,面試了 6 家公司 0 Offer,不知道問題出在哪,難道是杭州的 IT 崩盤了麽? 報名面試輔導後,經過一個多月的輔導打磨,現在成功入職某上市公司,漲薪 30%+,955 工作制,不咋加班,還不捲。 其他 ...
  • 引入依賴 <!--Freemarker wls--> <dependency> <groupId>org.freemarker</groupId> <artifactId>freemarker</artifactId> <version>2.3.30</version> </dependency> ...
  • 你應如何運行程式 互動式命令模式 開始一個互動式會話 一般是在操作系統命令行下輸入python,且不帶任何參數 系統路徑 如果沒有設置系統的PATH環境變數來包括Python的安裝路徑,可能需要機器上Python可執行文件的完整路徑來代替python 運行的位置:代碼位置 不要輸入的內容:提示符和註 ...