程式設計基礎·Java學習筆記·物件導向(下)

願你一生乾淨純潔發表於2022-03-22

Java程式設計基礎之物件導向(下)

(補充了上的一些遺漏的知識,同時加入了自己的筆記的ヾ(•ω•`)o)

(至於為什麼分P,啊大概是為了自己查筆記方便(?)應該是(〃` 3′〃))

(但是u1s1,學完了物件導向後反而更懵逼,下一步先刷演算法吧,然後Java的學習也跟上,今年爭取考完二級證照(o-ωq)).oO 困)

目錄

一、物件導向

(一)快捷鍵

(二)繼承

(三)封裝

(四)多型

(五)Object類

(六)關鍵字

(七)操作符

(八)抽象類

(九)介面

(十)內部類

 

 

一、物件導向

  (一)快捷鍵

  1.Eclipse:

   (1)setter and getter  右鍵 + Source

  2.Idea:

   (1)setter and getter  Alt + Insert

 

 

  (二)繼承

  1.概念:繼承是面嚮物件語言的重要機制。藉助繼承,可以擴充套件原有的程式碼,應用到其他程式中,而不必重新編寫這些程式碼。在java語言中,繼承是通過擴充套件原有的類,宣告新類來實現的。擴充套件宣告的新類稱為子類,原有的類稱為超類(父類)。繼承機制規定,子類可以擁有超類的所有屬性和方法,也可以擴充套件定義自己特有的屬性,增加新方法和重新定義超類的方法。(來自百度百科)

  2.在Java中,繼承是一種主要思想。通過父子類的繼承、抽象類的繼承、介面的繼承……可以通過繼承來完成呼叫。

  3.繼承的方法:

   (1)父子類:在物件導向(上)中,已經描述了繼承的方法,通過關鍵字extends完成父子類的繼承;

   (2)介面:介面是特殊的抽象類,我們能夠通過抽象類來呼叫方法,通過此方法呼叫後,只需要重寫介面的內容就可以呼叫;

  

 

  (三)封裝

  1.Java的封裝,就是把一些非公開的塊進行封裝,不讓使用者/呼叫者進行檢視,常見的形式是通過修飾詞的使用,如private來進行封裝;

  2.包裝類(Wrapper)

   (1)針對八種基本定義相應的引用型別——包裝類(封裝類)

 

基本資料型別 包裝類
boolean Boolean
byte Byte
short Short
int Integer
long Long
char Character
float Float
double Double

   (2)裝箱與拆箱

      a.基本資料型別包裝成包裝類:裝箱

//通過包裝類的構造器實現
int i = 500;
Integer t = new Integer(i);
//通過字串引數構造包裝類物件
Float f = new Float("4.56");
Long l = new Long("abcd");

      b.獲得包裝類物件中包裝的基本型別變數:拆箱

//呼叫包裝類的 .xxxValue();方法
Integer i = new Integer(112);
int i0 = i.intValue();

boolean b = new Boolean(false).booleanValue();

      c.自動裝箱

//等同於上文中的Integer i = new Integer(112);
Integer il = 112;

      d.自動拆箱

//自動拆箱Integer il = 112;
int i2 = i1;

//等同於boolean b = new Boolean(false).booleanValue();
boolean b = new Boolean(false);

      e.將字串轉換成基本資料型別

//通過包裝類的構造器實現
int i = new Integer("123");
//通過包裝類的parseXxx(String s)靜態方法
int i = Integer.parseInt("123");
float f = Float.parseFloat("0.123");
boolean b = Boolean.parseBoolean("false");

     f.將基本資料型別轉換成字串

//以上文中的i f b做示例
String istr = String.valueOf(i);
String fstr = String.valueOf(f);
String bstr = String.valueOf(ture);

 

 

  (四)多型

  1.多型性,是物件導向中最重要的概念,在Java中有兩種體現:

   (1)方法的過載與重寫(Overload and Override);

   (2)物件的多型性:可以直接應用在抽象類和介面上;

  2.方法的重寫:在子類中可以根據需要對從父類中繼承來的方法進行改造,也稱方法的重置、覆蓋。在程式執行時,子類的方法將覆蓋父類的方法。

    注意事項 :

    △ 重寫方法必須和被重寫方法具有相同的方法名稱、引數列表和返回值型別;

    重寫方法不能使用比被重寫方法更嚴格的訪問許可權;

    重寫和被重寫的方法須同時為static的,或同時為非static的子類方法丟擲的異常不能大於父類被重寫方法的異常

  3.子類可看做是特殊的父類,所以父類型別的引用可以指向子類的物件:即,向上轉型(upcasting);

  4.一個引用型別變數如果宣告為父類的型別,但實際引用的是子類物件,那麼該變數就不能再訪問子類中新增的屬性和方法

Student m = new Student();
m.school = “pku”;  //合法,Student類有school成員變數
Person e = new Student();
e.school = “pku”;  //非法,Person類沒有school成員變數。  屬性是在編譯時確定的,編譯時e為Person型別,沒有school成員變數,因而編譯錯誤。

   5.虛擬方法呼叫(Virtual Method Invocation)

//正常的方法呼叫
Person p = new Person();
p.getInfo();
Student s = new Student();
s.getInfo();

//虛擬方法呼叫(多型情況下)
Person e = new Student();
e.getInfo();
//呼叫Student類的getInfo()方法

  # 編譯時型別和執行時型別編譯時e為Person型別,而方法的呼叫是在執行時確定的,所以呼叫的是Student類的getInfo()方法。——動態繫結

  # 當呼叫成員變數時,因為成員變數不具備多型性,所以引用時,我們只考慮引用變數所屬類中是否有我們的屬性;

  # 而當呼叫成員方法時,我們在編譯時,要檢視引用變數所屬的類中是否有所呼叫的方法,所有需要我們的父子類中都存在方法體,但是當我們執行時,只考慮呼叫的實際物件所屬的類中的重寫方法;

  6.多型小結

  (1)成員方法:

    編譯時:要檢視引用變數所屬的類中是否有所呼叫的方法。

    執行時:呼叫實際物件所屬的類中的重寫方法。

  (2)成員變數:不具備多型性,只看引用變數所屬的類。

 

 

  (五)Object類

  1.Object類是所有Java類的根父類;

  2.Object類的主要方法:

   (1)public Object()                # 構造方法

   (2)public boolean equals(Object obj)       # 物件比較

   (3)public int hashCode()             # 取得Hash碼

   (4)public String toString()            # 取得地址

  3.物件型別轉換(Casting)

   (1)基本型別資料轉換:小的資料型別可以自動轉換成大的資料型別;

      強制型別轉換:大的資料型別轉換到小的資料型別則需要進行強轉,表示方法為:long a = (long) b;  float x = (float) y;

   (2)Java物件的強制型別轉化(造型)

      在下圖的程式碼中,Person類中是沒有方法體getschool的,所以此時我們需要呼叫方法時,需要將Person e強轉為Student,此時就可以呼叫方法getschool;

public class Test{
public void method(Person e) {
    //設Person類中沒有getschool()方法
    // System.out.pritnln(e.getschool());
    //非法,編譯時錯誤
if(e instanceof Student){
Student me = (Student)e;
    //將e強制轉換為Student型別
System.out.pritnln(me.getschool());
  }
}
public static void main(Stirng args[]){
Test t = new Test();
Student m = new Student();
t.method(m);
  }
}

 

 

  (六)關鍵字

  1.this 關鍵字

   (1)使用this關鍵字:在一個例項方法或一個構造器中,關鍵字this是對當前物件的引用。所謂當前物件,指的是其方法或構造器正在被呼叫的物件,也就是正在呼叫的方法或構造器所在的物件。可以通過this在一個例項方法或構造器中引用當前物件的任何成員。

   (2)最經常使用this關鍵字的情況,是在物件的一個欄位被方法或構造器的引數遮蔽時,需要呼叫這個被遮蔽的欄位的這種情況。

   (3)對構造器使用this:在一個構造器中,還可以使用this關鍵字來呼叫同一個類中的另外的構造器,這種做法稱為“顯式構造器呼叫”。

//this在方法內部使用,即這個方法所屬物件的印象
//this在構造器內部使用,表示該構造器正在初始化的物件
//  @this表示當前物件,可以呼叫類的屬性、方法和構造器

public class Person {

    //構造體中this的呼叫
    public Person(){}                        //

    public Person(int age){                  //
        this.age = age;
    }
    public Person(String name){              //
        this();                    //此句則表示進行了①的呼叫
        this.name = name;
    }

    public Person(int age,String name){
        this(1);                   //進行了②的呼叫
//Attention!!this進行構造體的呼叫時,要寫在方法的第一句 //this表示的是構造器中初始化的age,而後面的age表示的是形參的age this.age = age; this.name = name; } int age; String name; public void setName(String name){ //this表示的是方法中這個方法所屬物件的印象,而後面的name表示的是形參的name this.name = name; } public void setName01(String name) { //this表示呼叫的是setName方法,而後面的name表示的是形參的name this.setName(name); } public void showInfo(){ System.out.println("姓名:" + this.name); System.out.println("年齡:" + this.age); } }

  2.super 關鍵字

   (1)在Java類中使用super來呼叫父類中的指定操作:

   (2)super可用於訪問父類中定義的屬性

   (3)super可用於呼叫父類中定義的成員方法

   (4)super可用於在子類構造方法中呼叫父類的構造器


    注意事項:

    △ 尤其當子父類出現同名成員時,可以用super進行區分

    △ super的追溯不僅限於直接父類

    △ super和this的用法相像,this代表本類物件的引用,super代表父類的記憶體空間的標識

  3.this與super的區別

序號 區別 this super
1 訪問屬性 訪問本類中的屬性,如果本類沒有此屬性則從父類中繼續查詢 訪問父類中的屬性
2 呼叫方法 訪問本類中的方法 直接訪問父類中的方法
3 呼叫構造器 呼叫本類構造器,必須放在構造器首行 呼叫父類構造器,必須放在子類構造器的首航
4 特殊 表示當前物件 (/ω\*)……… (/ω•\*)沒有啦

   4.static關鍵字

    (1)在Java中,static可以用來修飾屬性、方法、程式碼塊、內部類;

    (2)類變數(class Variable):被static所修飾的變數就是類變數,他是靜態的,如果不想變數被改變,那麼就可以使用靜態變數;

         類變數(類屬性)由該類的所有例項共享;類變數不需要通過例項化就可以進行使用;

    (3)類方法(class Method):被static所修飾的方法就是類方法;

      沒有物件的例項時,可以用 類名.方法名() 的形式訪問由static標記的類方法;同時,在類方法中只能訪問類的static屬性;

      因為不需要例項化就能訪問,所以類方法中不能有 thissuper 關鍵字;

    (4)程式碼塊中,優先執行靜態程式碼塊,其次是程式碼塊,然後才是其他方法;

  5.final關鍵字

    (1)在Java中,final關鍵字用來表示“最終”的意思;

    (2)final標記的類不能被繼承;

    (3)final標記的方法不能被子類重寫;

    (4)我們稱final修飾的變數為常量,只能被賦值一次,名稱大寫;

 

 

  (七)操作符

  1.instanceof操作符

    x instanceof A:檢驗x是否為類A的物件,返回值為boolean型。要求x所屬的類與類A必須是子類和父類的關係,否則編譯錯誤。如果x屬於類A的子類B,x instanceof A值也為true。

public class Person extends Object {…}
public class Student extends Person {…}
public class Graduate extends Person {…}

public void method1(Person e) {
if (e instanceof Person)       //處理Person類及其子類物件
if (e instanceof Student)      //處理Student類及其子類物件
if (e instanceof Graduate)     //處理Graduate類及其子類物件
}

     # 要求x所屬的類與類A必須是子類和父類的關係,否則編譯錯誤;

     # 如果x屬於類A的子類B,x instanceof A值也為true;

   2. 【==】操作符 && equals操作符

   (1)【==】操作符基本型別比較:只要兩個變數的值相等,即為ture;

      引用型別比較引用(是否指向同一個物件):只有指向同一個物件時,才返回ture;

      用【==】進行比較時,符號兩邊的資料型別必須相容(可自動轉換的基本型別除外),否則編譯出錯;

   (2)equals():所有類都繼承了Object,也就獲得了equals()方法,還可以重寫;

      只能比較引用型別,其物件與【==】相同,比較是否指向同一個物件;

      特例:使用equals對File、String、Data及包裝類來說,是比較型別及內容而不考慮引用的是否是同一個物件;

       原因:在這些類中重寫了Object類的equals方法。  

 

 

   (八)抽象類

  1.用abstract關鍵字來修飾一個類時,這個類叫做抽象類;用abstract來修飾一個方法時,該方法叫做抽象方法;

  2.抽象方法:只有方法的宣告,沒有方法的實現;以分號結束:abstract int abstractMethod(int a);

  3.含有抽象方法的類必須被宣告為抽象類

  4.抽象類不能被例項化。抽象類是用來作為父類被繼承的,抽象類的子類必須重寫父類的抽象方法,並提供方法體。若沒有重寫全部的抽象方法,仍為抽象類;

  5.不能用abstract修飾屬性、私有方法、構造器、靜態方法、final的方法;

 

  (九)介面(interfac)

  1.介面是特殊的抽象類;

  2.在我們進行父子類的呼叫時,因為Java不支援多重繼承,所以我們可以通過介面進行多重的繼承,只需要重寫方法體即可;

  3.實現介面:class 類名 implements 介面名{  }

  4.一個類可以實現多個介面,通過“ ,”進行多個介面的串聯;介面也可以繼承其他介面;

  5.介面的特點:用interface來定義;

   介面中的所有成員變數都預設是由public static final修飾的;

   介面中的所有方法都預設是由public abstract修飾的;

   介面沒有構造器;

   介面採用多層繼承機制。

  6.實現介面的類中必須提供介面中所有方法的具體實現內容,方可例項化;否則,仍為抽象類;

   介面的主要用途就是被實現類實現(面向介面程式設計);

   與繼承關係類似,介面與實現類之間存在多型性;

   定義Java類的語法格式:先寫extends,後寫implements;

 

  (十)內部類(Inner class)

  1.在類中寫的類就是內部類;

  2.匿名內部類:不能定義任何靜態成員、方法和類,只能建立匿名內部類的一個例項;一個匿名內部類一定是在new的後面,用其隱含實現一個介面或實現一個類;

  3.內部類的作用:解決Java中不能多重繼承的問題;通過內部類繼承來繼承多個類進行重寫;

  4.內部類的使用方法;

 

public class Test{
    int i;
    public int z;
    private int k;
 
    //內部類 A
    class A{
        public void setTestFileds(){
            //在Test類中的成員變數,所以不能直接通過this呼叫,而是Test.this
            Test.this.i = 1;
            Test.this.z = 2;
            Test.this.k = 3;
            }
        }

    //呼叫類A
    public void setInfo(){
        new A().setTestFileds();
        }

    //輸出類A
    public void showInfo(){
        System.out.println(this.i);
        System.out.println(this.z);
        System.out.println(this.k);
        }
}

 

相關文章