程序設計基礎·Java學習筆記·面向對象(下)

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);
        }
}

 

Tags: