1. 程式人生 > >面向物件---封裝(Encapsulation)

面向物件---封裝(Encapsulation)

首先我們定義一個Person類的物件,裡面放入人的相關資訊

  我們再從外部用物件呼叫person類裡面其中的一個年齡,進行訪問輸出

  這時候我們就發現了一個問題,要是我們從外部傳入一個負數進來呢,這是不合邏輯的

其次我們就在person類中把age私有化

  但是私有化卻只能在內類中訪問,外部無法訪問

  我們就要在person類中建立一個訪問方法

  一般來說,一個事物通常會對應兩個方法,一個set,一個get

但是這樣還是可以從外部呼叫訪問方法傳入一個負數進來

其實我們這樣做是為了可以在方法類中進行邏輯判斷語句,提高程式碼健壯性。

 

//封裝原則


class
Person { private int age; //2、我們就用private隱藏起來,外界物件無法訪問,只能在本類中訪問 //3、但是人應該有年齡,就需要在person類中提供對應的訪問方式 public void SetAge(int a) // 這就是一個訪問方法---3 { if(a>0&&a<130){ age=a; } else System.out.println("error"); } public int GetAge() //
這就是一個訪問方法---3 { return age; } //4、一個事物通常會對應兩個方法,一個set,一個get void speak() { System.out.println("age="+age); } } class PersonDemo { public static void main(String[] args) { Person p=new Person(); //p.age=-20; //1、一般來說人的年齡不能負,這就違背了原則,就把年齡隱藏起來 p.SetAge(-20); //
呼叫訪問方法,訪問年齡,雖然這個可以傳遞負數,但是可以在方法類中進行邏輯判斷語句,提高程式碼健壯性---3 p.speak(); } }

 

從以上分析中,這就運用了Java面向物件中的一個關鍵字private

private:私有許可權修飾符,用於修飾類中的成員(成員變數,成員函式)

     私有僅僅是封的一種表現形式


 

 

一個人都會有一些自帶的屬性,比如:姓名和年齡

  每建立一個人的時候就要進行初始化,把這個人的特性展現出來

這時候就要運用建構函式的特點

由於,建構函式只執行一次,如果要多次呼叫,還是要建立一般方法

我們也就在分析事物中,該事物具備一些特性或行為,就把這些內容定義在建構函式中

再來說一個構造程式碼塊

  作用:給物件進行初始化。

  物件一建立就執行,而且由於建構函式執行。

  構造程式碼塊和建構函式的區別:  

    構造程式碼塊是給所有物件進行統一初始化

    建構函式是給對應的物件初始化

  構造程式碼塊中定義的是不同物件共性的初始化內容。

class Person
{
    private String name;
    private int age;
    Person()
    {
        System.out.println("A:name="+name+",age="+age);
        //cry();   //全部放到構造程式碼塊中
    }
    //構造程式碼塊
    {
        System.out.println("person code run");
        cry();
    }
    Person(String n)
    {
        name=n;
        System.out.println("B:name="+name+",age="+age);
        //cry();
    }
    Person(String n,int a)
    {
        name=n;
        age=a;
        System.out.println("A:name="+name+",age="+age);
        //cry();
    }
    public void SetName(String n){
        name=n;
    }
    public String GetName(){
        return name;
    }
    public void cry(){
        System.out.println("cry..............");
    }
}

class PersonDemo2
{
    public static void main(String[] args) {
        Person p1=new Person();  //如果把person類中的person()註釋掉,則會報錯,因為類中已經定義建構函式,所以不會預設
       // Person p1=new Person();  //想要一個孩子哭兩次,就定義一般方法,一個物件多次呼叫,而這個則是定義了兩個孩子,才能哭兩次。
                                 //這就是一般方法和構造方法的區別
        Person p2=new Person("lis");
        //System.out.println(p2.GetName());
        //p2.SetName("libusi");
        //System.out.println(p2.GetName());
        Person p3=new Person("wangwu",20);
    }
}

 

為了區分區域性變數與成員變數,我們可以用this關鍵字,來區分同名的情況

  對於this來說,哪個物件在呼叫了this所在的函式,this就代表哪個物件this應用

this的應用:

  用於建構函式間的呼叫

  只能定義建構函式第一行,因為初始化要先執行。  

class Person
{
    private String name;
    private int age;

    Person(String name)
    {
        //this.name="haha";
        this.name=name;
    }
    Person(String name,int age)
    {
        // this.name=name;  //物件一呼叫就執行了,執行的是物件裡面的,例如"lisi"
        //對於一般函式來說是Person(name)來呼叫,但是對於建構函式來說是this(name)
        this(name);  //p(name)  但是這個還會呼叫一下上面的建構函式,例如“haha”
        this.age=age;
    }
}

class PersonDemo4
{
    public static void main(String[] args) {
        Person p=new Person("lisi",30);
        Person p1=new Person(name)
    }
}


static靜態關鍵字

  

class Person
{
    String name;  //1、這稱為成員變數,例項變數--也是物件的變數,物件在,他就在
    static String country="CN";//2、因為多個物件中都會具有這個值,所以把它單獨提出來,做一個靜態,每個物件中都會存在一份,就是物件所共享
                               //3、靜態的成員變數,類變數,隨著類的載入而載入
    public void show()
    {
        System.out.println(name+"::"+country);
    }
}

class StaticDemo
{
    public static void main(String[] args) {
        // Person p=new Person();
        // p.name="zhangsan";
        // p.show();
        System.out.println(Person.country);
    }
}
// 什麼時候定義靜態函式呢? // 當功能內部沒有訪問到費靜態資料費靜態資料(物件的特有資料) // 那麼該功能就可以定義成靜態的
class Person
{
    String name;
    public void show() //public static void show() 
    {
        System.out.println(name+"haha");  //像這樣訪問到特有資料時,就不能加static
    }
}

class StaticDemo2
{
    public static void main(String[] args) {

        Person.show();  //像一個沒有訪問到特有資料name時,就把方法定義成靜態
    }
}

靜態的利與弊

  利:對物件的共享資料進行單獨空間的儲存,節省空間,沒有必要每一個物件都儲存一份,可以直接被類名呼叫

  弊:生命週期過長;訪問出現侷限性(靜態雖好,只能訪問靜態)


靜態程式碼塊:

 

  隨著類的載入而執行,只執行一次,優先於主函式,用於給類初始化
class StaticCode
{
    static{
        System.out.println("b");
    }
    public static void show()
    {
        System.out.println("show run");
    }
}

class StaticDemo3
{
    static
    {
        // System.out.println("b");  //第一個執行,因為靜態程式碼塊
    }
    public static void main(String[] args) {
        // new StaticCode();   //呼叫staticcode,輸出a
        // new StaticCode();  //因為是靜態程式碼塊,只執行一次,所以不再執行a
        // System.out.println("over");  //最後執行,over

        StaticCode s=null;  //這樣staticcode是不會執行的,因為傳遞的空值,沒有任何意義,只要運用類裡面的內容,才有效
        s=new StaticCode();  //這樣也算,因為方法會預設一個一個建構函式
    }
    static
    {
        // System.out.println("c");  //還是靜態程式碼塊,繼續執行
    }
}

//執行結果:b c a over

 

再就是對於類的一個面試題目

//一個面試題目

class StaticCode
{
    int num=9;  //2、如果在中新增一個num
    StaticCode()
    {
        System.out.println("b");
    }

    static
    {
        System.out.println("a");  //3、想要訪問這個num  是訪問不到的,因為num是非靜態成員,就是訪問不了
    }

    {
        System.out.println("c"+num);  //4、在構造程式碼塊中則可以執行,因為使用物件初始化
    }

    StaticCode(int x)
    {
        System.out.println("d");
    }

    public static void show()
    {
        System.out.println("show run");
    }
}

class StaticDemo4
{
    public static void main(String[] args) {
        new StaticCode(4);  
        //1、執行結果:a c d  因為優先訪問靜態程式碼塊,再訪問構造程式碼塊,最後建構函式帶引數的方法
    }
}