国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學院 > 開發設計 > 正文

封裝

2019-11-08 01:57:48
字體:
來源:轉載
供稿:網友

在描述對象時候,例如描述對象為狗,可以設置Dog.age= 100;看上去語法沒有任何毛病,但是顯然這么寫是不合理的。因此,java提供了封裝的機制,將類和對象的成員變量進行封裝。

案例1:

class FengZhuang{    publicstatic void main(String[] args){        Dogjinmao = new Dog();        jinmao.setAge(180);        //jinmao.age= 100;    }}class Dog{    PRivate int age;    public void setAge(intage){        if(age > 20){            System.out.println("滾犢子!");            return;        }        System.out.println("設置成功");        this.age = age;    }} 

概念:

封裝是面向對象三大特征之一,它指的是將對象的狀態信息隱藏在對象內部,不允許外部程序直接訪問對象內部信息,而是通過該類提供的方法來實現對內部信息的訪問。這樣,當我們設置屬性值的時候,可以判斷設置的屬性值是否合理。

//TODOprivate int age;    publicvoid setAge(int age){        if(age> 20){            System.out.println("滾犢子!");            return;        }        System.out.println("設置成功");        this.age= age;    } 

封裝是面向對象編程語言對客觀世界的模擬,在客觀世界里,對象的信息都是被隱藏在對象內部,外界無法直接操作訪問和修改。就如對Dog.age設置屬性那樣,外界不能直接修改age屬性,只能隨著歲月的流逝(條件),age才會增加。

封裝的目的:

1、  隱藏類的實現細節。

隱藏和封裝的區別:

隱藏就是將屬性私有化(private),不能被外界直接訪問。

封裝比隱藏多一步,另外提供公有的方法讓外界去操作該隱藏屬性。

如下:temp是內部實現功能的細節,只需要隱藏。而age是描述對象屬性,需要隱藏起來后提供公有方法對其進行訪問和設置。

class Dog{         //這個變量的業務邏輯只是在該對象方法中有一個記錄         //臨時數據功能         privateString temp;         privateint age;         publicvoid setAge(int age){                   temp= "這個狗狗的年紀是"+age;                   if(age> 20){                            System.out.println("滾犢子!");                            return;                   }                   System.out.println("設置成功");                   this.age= age;         }         publicint getAge(){         System.out.println(temp);                   returnage;         }}

2、讓使用者只能通過預定義的方法來訪問數據,從而可以在該方法中添加控制邏輯,限制對成員變量的不合理的訪問。

3、可進行數據檢查,從而有利于保證對象完整性。

4、提高代碼的可維護性。

為了實現良好的封裝,需要從兩個方面考慮:

1、將對象的成員變量和實現細節隱藏起來,不允許外部直接訪問。

2、將方法暴露出來,讓方法來控制對這些成員變量進行安全訪問和操作。

因此封裝實際上就是:將該隱藏的隱藏,將該暴露的暴露。而實現這一目的則是通過java提供的訪問控制符來實現。

 

訪問控制符(權限修飾符)

java提供3個訪問控制符關鍵字,private、protected、public分別代表三個訪問控制級別,另外還有一個默認訪問控制級別,一共4個訪問控制級別。

默認訪問控制即不寫權限修飾符(default)。

控制級別由小到大排序為:

private->default->protected->public

使用4種權限類型控制的效果:

private:修飾的成員(變量、方法、構造器)只能在當前類內部訪問,外界是無法獲取該成員。顯然,使用這個修飾符可以達到隱藏成員變量的目的。

class FengZhuang{    public static void main(String[] args){        Dog jinmao = new Dog();        jinmao.age = 100;    }}class Dog{    private int age; }

default:默認修飾符,不適用任何修飾符關鍵字修飾。修飾的成員或類可以被相同包下的其他類訪問,不能被其他包下的類訪問。

案例:定義bao1. Bao1Class, bao1. Bao1Class2, bao2. Bao2Class,在bao2下的Bao2Class類無法訪問在bao1下的Bao1Class的name屬性。但是,bao1下的Bao1Class2類可以訪問在bao1下的Bao1Class的name屬性。

package bao1;public class Bao1Class{    staticString name;} package bao2;import bao1.*;public class Bao2Class{    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }} package bao1;public class Bao1Class2{    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }}

protected:子類訪問權限修飾符,修飾的成員可以被同包、不同包下的子類訪問。通常使用該修飾符修飾的方法,希望其子類能重寫這個方法。

package bao1;public class Bao1Class{    staticprotected String name;}Bao2Class不可以訪問Bao1Class的name屬性package bao2;import bao1.*;class Bao2Class {    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }}package bao1;public class Bao1Class{    staticprotected String name;}Bao2Class可以訪問Bao1Class的name屬性,因為有繼承關系package bao2;import bao1.*;class Bao2Class extends Bao1Class {    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }}

public:公開訪問權限,這是最寬松的訪問權限級別,修飾的成員、類,那么這個成員或者外部類可以被所有包下所有類訪問。

權限最大,在任意位置,都可以訪問(注意:導包)

 

修飾符修飾類:

注意:外部類只能用public 或者默認權限修飾,不能使用private、protected來修飾。

因為被這兩個修飾的類不能被訪問,也就沒有任何意義。

//TODO代碼驗證權限修飾符

測試public修飾的類:

package bao1;public class Bao1Class{    staticpublic  String name;} package bao2;import bao1.*;class Bao2Class{    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }} 默認修飾符(default):package bao1;class Bao1Class{    staticpublic  String name;}

這樣是無法訪問的,因為Bao1Class權限僅限bao1包下,bao2中的類無法訪問。

package bao2;import bao1.*;class Bao2Class extends Bao1Class{    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }}

這樣是可以訪問的,因為Bao1Class2和Bao1Class在一個包下。

package bao1;class Bao1Class2{    publicstatic void main(String[] args){        Bao1Class.name= "小明";    }}

不能使用private和protected修飾類

總結已學的修飾符。

static:靜態修飾符;

private:私有權限修飾符;

default:默認權限修飾符;

protected:子類權限修飾符;

public:公開的權限修飾符。

 

當使用private修飾構造器的時候,會出現什么情況?

Private修飾的方法,作用范圍是:類本身,其他類不能調用。

 

那么將對象的構造器方法都私有后,就無法創建對象了,那么在實際應用中,還可以通過暴露一個公開的方法,讓外界獲取一個對象。

 

    classDuoTai    {        publicstatic void main(String[] args){            Personperson = Person.getPerson();            person.method();        }    }    classPerson    {        privatePerson(){            System.out.println("構造器方法執行");        }        publicstatic Person getPerson(){            returnnew Person();        }        public  void method(){            System.out.println("執行person中的方法");        }    } 

單例設計模式

這種案例在實際開發中,我們以單例模式舉例。

當我們上網時候,發現顧客是多個,但是服務生是一個,并不是一個顧客有一個服務生。

那在這個時候,網管就是唯一的,那網管就是單例對象。

 

單例模式(Singleton Pattern)是 Java中最簡單的設計模式之一。這種類型的設計模式屬于創建型模式,它提供了一種創建對象的最佳方式。

這種模式涉及到一個單一的類,該類負責創建自己的對象,同時確保只有單個對象被創建。這個類提供了一種訪問其唯一的對象的方式,可以直接訪問,不需要實例化該類的對象。

注意:

·        1、單例類只能有一個實例。

·        2、單例類必須自己創建自己的唯一實例。

·        3、單例類必須給所有其他對象提供這一實例。

意圖:保證一個類僅有一個實例,并提供一個訪問它的全局訪問點。

主要解決:一個全局使用的對象頻繁地創建與銷毀。

何時使用:當您想控制實例數目,節省系統資源的時候。

如何解決:判斷系統是否已經有這個單例,如果有則返回,如果沒有則創建。

關鍵代碼:構造函數是私有的。

更多相關資料請查閱:http://www.runoob.com/design-pattern/singleton-pattern.html

代碼實現:

class Singleton{    publicstatic  void main(String[] args){        /*顯然,這種情況不符合常理            實際中,一個網管,服務多個顧客,            網管就是唯一的,我們把網管對象變為唯一            對象,就符合常理了。        */        Customerc1 = new Customer();        c1.surfing();        Customerc2 = new Customer();        c2.surfing();        Customerc3 = new Customer();        c2.surfing();    }}class Customer{    publicvoid surfing(){        Waiterwaiter = Waiter.getWaiter();        waiter.kaiji();    }}class Waiter{    privateWaiter(){       }    privatestatic  Waiter waiter;    publicstatic Waiter getWaiter(){        //這個時候,我要保證每次獲取網管對象都是唯一的        if(waiter== null){            waiter= new Waiter();            returnwaiter;        }        returnwaiter;     }    int temp =0;    publicvoid kaiji(){        System.out.println("開機" + temp +"號電腦");        temp++;    }} 

接下來介紹單例模式的兩種實現方式:

1、  懶漢式,顧名思義,獲取單例對象的操作采用偷懶的方式。

在代碼中,那就是說:你什么時候需要用到該對象,那么什么時候再創建。

如下代碼:當調用getWaiter方法獲取對象時,才會創建對象。而不調用getWaiter方法的話,是不會創建對象的。

 

class Waiter{    private Waiter(){       }    privatestatic  Waiter waiter;    publicstatic Waiter getWaiter(){        //這個時候,我要保證每次獲取網管對象都是唯一的        if(waiter== null){            waiter= new Waiter();            returnwaiter;        }        returnwaiter;     }    int temp =0;    publicvoid kaiji(){        System.out.println("開機" + temp +"號電腦");        temp++;    }} 

2、  餓漢式

和懶漢式相反,在類存在的時候,該類型對象就存在了!即便你沒有調用getWaiter方法,該對象也存在!

class Waiter{    privateWaiter(){   }    privatestatic  Waiter waiter = new Waiter();    publicstatic Waiter getWaiter(){        /*這個時候,不管有沒有調用該方法,        返回的對象就已經存在了!而且該對象            屬于類,所以每次調用該方法,返回            的就是唯一的Waiter*/        returnwaiter;     }    int temp =0;    publicvoid kaiji(){        System.out.println("開機" + temp +"號電腦");        temp++;    }} 

其實這兩種單例模式在開發中也并不是非常完美,但是作為現階段,我們只需熟練編寫上面兩個案例即可,如果還有興趣,可以參考下面鏈接的文章,還有其他創建單例對象的方式(按住ctrl鍵單擊)。

http://www.runoob.com/design-pattern/singleton-pattern.html

 

 

 

 

 

思考案例:

情況1:

定義Person類,定義Man類,兩個類不在同一個包下

package bao1;public class Person{    protectedint age;} import bao1.Person;public class Man{    Person p = new Person();    publicvoid setAge(){        p.age= 12;    }}

編譯Man類會報錯,因為age屬性是protected修飾,必須是Person本包下或它的子類才可以訪問,這里Man即不在同一個包下,也不是Person子類!

情況2:

定義Person類,定義Man類,兩個類不在同一個包下

package bao1;public class Person{    protectedint age;}

 

 

 

 

import bao1.Person;public class Man extends Person{    Person p = new Person();    publicvoid setAge(){        p.age= 12;    }}

這種情況還是會報錯,因為雖然Man繼承了Person,但是,實際上訪問age屬性的還是Person對象,這里并不滿足Man類和Person類在同一包下,也不滿足調用age屬性的對象是Person對象的子類。這里的p指的是Person類型對象,不是他的子類對象。

情況3:

正確的情況:

定義Person類,定義Man類,兩個類不在同一個包下

package bao1;public class Person{    protectedint age;} 

 

 

 

import bao1.Person;public class Man extends Person{    Man p =new Man();    publicvoid setAge(){        p.age= 12;    }}

 

這里,p.age是可以的,雖然Man不和Person在同一個包下,但是,創建出來訪問age屬性的對象是Person類型對象的子類對象,符合protected權限修飾符的訪問范圍,所以不報錯!

 

情況4:

編寫測試類TestPro,測試并思考:

package bao1;public class Person{    protectedint age;}

 

import bao1.Person;public class Man extends Person{    public intgetAge(){        returnthis.age;    }    publicvoid setAge(int age){        this.age= age;    }}

 

 

class TestPro{    publicstatic void main(String[] args){        Manman = new Man();           man.setAge(123);        intage = man.getAge();        System.out.println(age);    }}

 

這里通過測試類創建man對象,然后調用Man對象的age屬性。

在man對象中,this代表的是當前對象,這個當前對象又是Person類的子類對象,所以是可以訪問protected修飾的age屬性,所以不會報錯!!

 

 


上一篇:計算機輸出設備

下一篇:第三次作業DDS

發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 满洲里市| 南丹县| 泽州县| 梅州市| 西宁市| 临澧县| 慈利县| 丹凤县| 绥宁县| 青铜峡市| 清水县| 富顺县| 洪泽县| 灌南县| 黄龙县| 三河市| 呼伦贝尔市| 隆德县| 浦城县| 卫辉市| 九台市| 延川县| 元江| 安远县| 荃湾区| 齐河县| 正安县| 弥渡县| 清原| 巴林左旗| 遂宁市| 辉县市| 咸宁市| 万年县| 洪洞县| 南华县| 读书| 宜城市| 浪卡子县| 丰县| 浦城县|