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屬性;
因為不需要例項化就能訪問,所以類方法中不能有 this 和 super 關鍵字;
(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); } }