1. 程式人生 > >044_面向對象_17_封裝

044_面向對象_17_封裝

高內聚 class 車輛 public -c set 操作 pub image

一、封裝的概念

  制造廠家為了方便我們使用對象(電視、車輛),把復雜的內部細節全部封裝起來。只給我們暴露簡單的接口,比如:電源開關、比如:油門。具體怎麽內部實現的,我們不需要操心。需要讓用戶知道的暴露出來,不需要讓用戶了解的全部隱藏起來。這就是封裝。

  我要看電視,只需要按一下開關和換臺就可以了。有必要了解電視機內部的結構嗎?有必要碰碰顯像管嗎?

二、為什麽需要封裝?封裝的作用和含義?  

  專業:我們程序設計要追求“高內聚,低耦合”。高內聚就是類的內部數據操作細節自己完成,不允許外部幹涉;低耦合:僅暴露少量的方法給外部使用。
  編程中封裝的具體意義:便於調用者調用。
  良好的封裝,便於修改內部代碼,提高可維護性。
  良好的封裝,可進行數據完整性檢測,保證數據的有效性。
三、使用訪問控制符(private、default、protected、public),實現封裝

  

同一個類

同一個包中

子類

所有類

private

*

default(即不加修飾符的時候)

*

*

protected

*

*

*

public

*

*

*

*

四、封裝的使用細節

  1.屬性一般使用private.(除非本屬性確定會讓子類繼承並且使用時)才提供相應的get/set方法來訪問相關屬性. 這些方法通常是public,從而提供其他類對屬性的讀取操作。 (註意:boolean變量的get方法是用:is開頭!)
  2.一些只用於本類的輔助性方法可以用private,希望其他類調用的方法用public。

五、演示示例

  一、private修飾符

  1.測試private修飾符所修飾的屬性或方法在同一類中是否能被訪問  

package edu.aeon.test;
/**
 * [說明]:測試訪問控制符
 * @author aeon
 * 測試步驟:
 *     1、測試private修飾的方法或屬性是否能在當前類(本類)中被調用?(結果:可以被調用)
 *     2、測試private修飾的方法或屬性在非本類(同包的其它類/子類、不同包其他類/子類、)中是否能被調用?(結果:不可以被調用)
 */
public class A {
    //比如我們將本類的一個屬性a用private修飾(私有化)
    private int a=10;
    private void seeA(){
        //測試用private修飾的屬性是否在本類中可見、
        System.out.println(this.a);
    }
    public static void main(String[] args) {
        A a=new A();
        //測試結果:用private修飾的屬性、在本類中可以調用!
        System.out.println(a.a);
        a.seeA();
    }
}

測試結果截圖:

  技術分享圖片

2、測試private修飾符所修飾的屬性或方法在同一包中的子類中是否能被訪問

演示示例:

package edu.aeon.test;
/**
 * [說明]:測試訪問控制符
 * @author aeon
 * 測試步驟:
 *     1、測試private修飾的方法或屬性是否能在當前類(本類)中被調用?(結果:可以被調用)
 *     2、測試private修飾的方法或屬性在非本類(同包的其它類/子類、不同包其他類/子類、)中是否能被調用?(結果:不可以被調用)
 */
public class A {
    //比如我們將本類的一個屬性a用private修飾(私有化)
    private int a=10;
    private void seeA(){
        //測試用private修飾的屬性是否在本類中可見、
        System.out.println(this.a);
    }
    public static void main(String[] args) {
        A a=new A();
        //測試結果:用private修飾的屬性、在本類中可以調用!
        System.out.println(a.a);
        a.seeA();
    }
}
package edu.aeon.test;
/**
 * [說明]:測試private修飾的屬性或者方法在同一包中的子類中是否能被訪問(測試結果:不能被訪問)
 * @author aeon
 *
 */
public class B extends A{

    public static void main(String[] args) {
        A a=new A();
        System.out.println(a.a);
        a.seeA();
        /*我們測試一個在父類中根本不存在的方法或者屬性:顯然從測試結果可以看出來、父類中用private修飾的屬性或者方法所報的錯誤
        和調用一個父類中根本不存在的屬性和方法所報的錯誤是不一樣的。*/
        a.seeAd();
    }

}

運行結果截圖:

  技術分享圖片

3、測試private修飾符所修飾的屬性或方法在不同一包中的子類中是否能被訪問

  測試結果:這個肯定不能被訪問了,同包子類中不能訪問、不同包中的子類更加就不能訪問了!

測試結論:

  1、用private修飾的屬性或者方法只能在本類中調用、其它(同一包中[類/子類]/不同包中[類/子類])均不能訪問!

  2、測試結果可以看出來、父類中用private修飾的屬性或者方法所報的錯誤和調用一個父類中根本不存在的屬性和方法所報的錯誤是不一樣的、可見編譯器能識別一個private修飾的屬性和方法和調用一個根本不存在的方法。

  二、默認(不寫)修飾符

  1.測試默認(不寫)修飾符的屬性或方法在同一包的同一類中是否能被訪問  

package edu.aeon.test;
/**
 * [說明]:測試默認(不寫時)訪問控制符
 * @author aeon
 * 測試步驟:
 *     1、測試不寫訪問修飾的方法或屬性是否能在當前類(本類)中是否能被訪問?(結果:可以被訪問)
 *     2、測試不寫訪問修飾的方法或屬性在同一包中的其它類中是否能被訪問(結果:可以被訪問)
 *     3、測試不寫訪問修飾的方法或屬性在不同包中的其它類中是否能被訪問(結果:不可以被訪問)
 *     4、測試不寫訪問修飾的方法或屬性在不同包中的其它子類中是否能被訪問(結果:不可以被訪問)
 *     結論:可見默認(不寫)訪問控制符修飾的屬性和方法界限是同一包中、不同包中的其它類及其子類均不能被訪問
 */
public class A {
    //比如我們將本類的一個屬性a用默認(不寫)訪問控制符修飾
    int a=10;
    void seeA(){
        //默認(不寫)修飾符的屬性是否在本類中可見、
        System.out.println(this.a);
    }
    public static void main(String[] args) {
        A a=new A();
        //測試結果:默認(不寫)修飾的屬性、在本類中可以調用!
        System.out.println(a.a);
        a.seeA();
    }
}

測試結果截圖:

  技術分享圖片

  2、測試不寫訪問(默認)修飾的方法或屬性在同一包中的其它類中是否能被訪問(結果:可以被訪問)

  

package edu.aeon.test;
/**
 * [說明]:測試默認(不寫時)訪問控制符
 * @author aeon
 * 測試步驟:
 *     1、測試不寫訪問修飾的方法或屬性是否能在當前類(本類)中是否能被訪問?(結果:可以被訪問)
 *     2、測試不寫訪問修飾的方法或屬性在同一包中的其它類中是否能被訪問(結果:可以被訪問)
 *     3、測試不寫訪問修飾的方法或屬性在不同包中的其它類中是否能被訪問(結果:不可以被訪問)
 *     4、測試不寫訪問修飾的方法或屬性在不同包中的其它子類中是否能被訪問(結果:不可以被訪問)
 *     結論:可見默認(不寫)訪問控制符修飾的屬性和方法界限是同一包中、不同包中的其它類及其子類均不能被訪問
 */
public class A {
    //比如我們將本類的一個屬性a用默認(不寫)訪問控制符修飾
    int a=10;
    void seeA(){
        //默認(不寫)修飾符的屬性是否在本類中可見、
        System.out.println(this.a);
    }
    public static void main(String[] args) {
        A a=new A();
        //測試結果:默認(不寫)修飾的屬性、在本類中可以調用!
        System.out.println(a.a);
        a.seeA();
    }
}
package edu.aeon.test;
/**
 * [說明]:測試default(不寫時)修飾的屬性或者方法在同一包類中是否能被訪問(測試結果:能被訪問)
 * @author aeon
 *
 */
public class B{

    public static void main(String[] args) {
        A a=new A();
        System.out.println(a.a);
        a.seeA();
        /*我們測試一個在父類中根本不存在的方法或者屬性:顯然從測試結果可以看出來、父類中用private修飾的屬性或者方法所報的錯誤
        和調用一個父類中根本不存在的屬性和方法所報的錯誤是不一樣的。*/
    }

}

測試結果:

  技術分享圖片

  3、測試不寫訪問修飾的方法或屬性在不同包中的其它類中是否能被訪問(結果:不可以被訪問)

  

package edu.aeon.test1;

import edu.aeon.test.A;

/**
 * [說明]:測試不寫訪問修飾符的屬性或者方法在不同包中的類中是否能被訪問(測試結果:不能被訪問)
 * @author aeon
 *
 */
public class C{

    public static void main(String[] args) {
        A a=new A();
        System.out.println(a.a);
        a.seeA();
        /*我們測試一個在父類中根本不存在的方法或者屬性:顯然從測試結果可以看出來、父類中用private修飾的屬性或者方法所報的錯誤
        和調用一個父類中根本不存在的屬性和方法所報的錯誤是不一樣的。*/
    }

}

測試結果:

  技術分享圖片

  4、測試不寫訪問修飾的方法或屬性在不同包中的其它子類中是否能被訪問(結果:不可以被訪問)

  

package edu.aeon.test1;

import edu.aeon.test.A;

/**
 * [說明]:測試不寫訪問修飾符的屬性或者方法在不同包中的子類中是否能被訪問(測試結果:不能被訪問)
 * @author aeon
 *
 */
public class D extends A{

    public static void main(String[] args) {
        A a=new A();
        System.out.println(a.a);
        a.seeA();
        /*我們測試一個在父類中根本不存在的方法或者屬性:顯然從測試結果可以看出來、父類中用private修飾的屬性或者方法所報的錯誤
        和調用一個父類中根本不存在的屬性和方法所報的錯誤是不一樣的。*/
    }

}

測試結果:

  技術分享圖片

結論:

  可見默認(不寫)訪問控制符修飾的屬性和方法界限是同一包中、不同包中的其它類及其子類均不能訪問!

五、總結

  1、通過private訪問控制符修飾的屬性或者方法只能在同一個類中能被訪問

  2、通過默認(不寫時)訪問控制符修飾的屬性或者方法只能在同一個類、同一個包中的其他類及同一個包中的子類中可以被訪問。記住此處的界限是包、其它包中的類及其子類均無法訪問。

  3、通過protected訪問控制符修飾的屬性或者方法只能在同一個類、同一個包中的其他類及其同一個包中的子類中可以被訪問。記住此處的界限是包、其它包中的類及其子類均無法訪問。(經測試結果發現和默認訪問控制符一樣?)

  4、通過public訪問控制符修飾的屬性或者方法在同一個類、同一個包中的其他類及其同一個包中的子類、不同包中的其它類、及其不同包中的子類均可以被訪問。

  

044_面向對象_17_封裝