0101-面向對象特性

1 面向對象

1.1 面向對象是什麼

  • 面向對象:object oriented programming OOP
  • 面向對象是一種開發方法,是一種思想
  • 面向對象是一種對現實世界的理解和抽象的方法,是計算機編程技術發展到一定階段後的產物

1.2 面向對象三大特性

1.2.1 封裝

  • 什麼是封裝
    封裝是指將數據與具體操作的實現代碼放在某個對象內部,使這些代碼的實現細節不被外界發現,外界只能訪問該對象對外開放的方法與屬性。

  • 封裝的好處
    封裝能隱藏對象實現細節,使代碼更易維護。同時因爲不能直接調用、修改對象內部的私有信息,在一定程度上保證了系統安全。

  • 舉例說明
    “人”本身可以看作一個完整的封裝,有姓名、年齡、性別等屬性,有走路、吃飯、睡覺等方法。
    性別、身高這些是對外暴露的屬性,別人直接可以知道。而體重、年齡、姓名等屬於個人隱藏屬性,只能通過特定等方法(詢問、稱量)才能獲取。

1.2.2 繼承

  • 什麼是繼承
    繼承在本質上是特殊——一般的關係,即常說的is-a關係。子類繼承父類,表明子類是一種特殊的父類,並且具有父類所不具有的一些屬性或方法。
    例如兒子繼承父親的財產。

  • 繼承的好處
    a. 可以複用這些類的方法和域;
    b. 可以添加新的方法和域,從而擴充了類的功能;

  • 繼承的缺點
    a. 打破了封裝性,子類依賴於超類的實現細節,和超類耦合;
    b. 超類(父類)更新後可能會導致錯誤;

  • 代碼示例:

class MyHashSet<E> extends HashSet<E> {
    private int count;

    @Override
    public boolean add(E o) {
        count ++;
        return super.add(o);
    }

    @Override
    public boolean addAll(Collection c) {
        if (c == null) {
            return false;
        }
        count += c.size();
        return super.addAll(c);
    }

    public int getCount() {
        return count;
    }

    public static void main(String[] args) {
        MyHashSet<Integer> myHashSet = new MyHashSet<Integer>();
        myHashSet.addAll(Arrays.asList(1,2,3));
        System.out.println("count:" + myHashSet.count);
    }
}

輸出結果:

count:6

運行後會發現,加入了3個元素之後,計數器輸出的值是6。原因分析:

進入到超類中的 addAll() 方法就會發現出錯的原因:它內部調用的是 add() 方法。所以在這個測試裏,進入子類的 addAll() 方法時,數器加3,然後調用超類的 addAll() ,超類的 addAll() 又會調用子類的 add() 三次,這時計數器又會再加三。

1.2.3 多態

  • 什麼是多態
    所謂多態,即多種形態。

    比如你是一個酒神,對酒情有獨鍾。某日回家發現桌上有幾個杯子裏面都裝了白酒,從外面看我們是不可能知道這是些什麼酒,只有喝了之後才能夠猜出來是何種酒。你一喝,這是劍南春、再喝這是五糧液、再喝這是酒鬼酒….在這裏我們可以描述成如下:

    酒 a = 劍南春
    酒 b = 五糧液
    酒 c = 酒鬼酒

    這裏所表現的的就是多態。劍南春、五糧液、酒鬼酒都是酒的子類,我們只是通過酒這一個父類就能夠引用不同的子類,這就是多態——我們只有在運行的時候纔會知道引用變量所指向的具體實例對象。

  • 多態的好處
    a. 同一類型的引用指向不同的對象時,有不同的實現;
    b. 同一個對象被造型爲不同的類型時,有不同的功能;

  • demo

//向上造型
public class UpDemo {
	public static void main(String[] args) {
		Boo o1 = new Coo(); //向上造型
		Coo o2 = (Coo)o1; //正確,o1所指向的對象就是Coo類型
		Inter3 o3 = (Inter3)o1; //正確,o1所指向的對象實現了Inter3接口
		//Doo o4 = (Doo)o1; //類型轉換異常(ClassCastException)
		
		if(o1 instanceof Doo){
			Doo o5 = (Doo)o1;
		}
	}
}
 
interface Inter3{
}
class Boo{
}
class Coo extends Boo implements Inter3{
}
class Doo extends Boo{
}

1.3 面向對象優點

1.3.1 面向對象

  • 優點:
    易維護、易複用、易擴展。由於面向對象有封裝、繼承、多態性的特性,可以設計出低耦合的系統,使系統更加靈活、更加易於維護。
  • 缺點:
    性能比面向過程低,設計成本高。

1.3.2 面向過程

  • 優點:
    性能比面向對象高,因爲類調用時需要實例化,開銷比較大,比較消耗資源,比如單片機、嵌入式開發、Linux/Unix等一般採用面向過程開發,性能是最重要的因素。
  • 缺點:
    沒有面向對象易維護、易複用、易擴展。

2 Java 四種修飾符

2.1 Java 的四種修飾符關鍵字

public、protected、default、private  

2.2 權限範圍

訪問權限 本類 本包 子類 其他包
public
protect x
default x x
private x x x

2.3 存在的原因

a. 讓調用者無法觸及他們不應該觸及的部分
b. 允許庫設計者可以改變類內部的工作方式而不用擔心會影響到調用者
c. 爲封裝、繼承和多態提供依據及保障

3 重載和重寫

3.1 方法的重載 (Overload)

3.1.1 什麼是方法重載

  • 一個類中,方法名稱相同,參數列表不同,稱方法的重載
  • 編譯器在編譯時,自動根據方法的簽名綁定調用不同的方法

3.1.2 方法重載的作用

  • 方便根據不同的參數個數,順序,類型,自動匹配方法,減少寫過個函數名或方法名的重複步驟
  • 不用爲了對不同的參數類型或參數個數,而寫多個函數

3.1.3 方法重載的意義

當對某個方法升級時,可以重載此方法,增加參數,減少因方法名改變引起的歧義。

3.1.4 demo

/*
 * 1.一個文件中可以包含多個類
 * 2.public修飾的類只能有一個
 * 3.public修飾的類必須與文件名相同
 */
//重載的演示
public class OverloadDemo {
	public static void main(String[] args) {
		Aoo o = new Aoo();
		o.say();
		o.say("zhangsan");
		o.say(23);
		o.say("zhangsan", 23);
		o.say(23, "zhangsan");
	}
}
 
class Aoo{
	void say(){}
	void say(String name){}
	void say(int age){}
	void say(String name,int age){}
	void say(int age,String name){}
	
	//int say(){ return 5;} //編譯錯誤,與返回值類型無關
	//void say(String address){} //編譯錯誤,與參數名無關
}

3.2 方法的重寫 (Override)

3.2.1 什麼是方法重寫

  • 發生在父子類中,方法名相同,參數列表相同,方法體不同
  • 重寫方法被調用時,看對象的類型

3.2.2 方法重寫的要求

  • 發生方法重寫的兩個方法返回值、方法名、參數列表必須完全一致
  • 子類拋出的異常下不能超過父類相應方法拋出的異常
  • 子類方法的訪問級別不能低於父類相應方法的訪問級別

3.2.3 方法重寫的作用

  • 重寫是爲了增強類的重用性和複用性,擴展性;
  • 重寫是對類中方法的擴充,因爲繼承用的是父類的東西,重寫則不僅得到父類的東西,同時也加入了自己的東西

3.2.4 demo

public class OverrideDemo {
	public static void main(String[] args) {
		OAoo o1 = new OBoo(); //向上造型,父類引用指向子類對象
		OAoo o2 = new OCoo();
		test(o1);
		test(o2);
	}
	public static void test(OAoo oo){
		oo.show();
	}
 
}
class OAoo{
	void show(){
		System.out.println("Aoo-show()");
	}
}
class OBoo extends OAoo {
	void show(){
		System.out.println("Boo-show()");
	}
}
class OCoo extends OAoo {
	void show(){
		System.out.println("Coo-show()");
	}
}

4 總結

  • 封裝隱藏了類的內部實現機制
  • 繼承是爲了複用父類代碼
  • 組合大於繼承,多用組合,少用繼承
  • 實現多態有三個必要條件:繼承、重寫、向上轉型
  • 重寫是爲了增強類的重用性和複用性,擴展性
  • 重載方便根據不同的參數個數,順序,類型,自動匹配方法

PS:如有疑問,歡迎指正。

推薦閱讀:
面向對象的五個特徵
Java太陽系小遊戲分析和源碼
面向對象學習筆記

------ 更多內容歡迎關注 ----------
更多內容歡迎關注

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章