面向物件---封裝(Encapsulation)
首先我們定義一個Person類的物件,裡面放入人的相關資訊
我們再從外部用物件呼叫person類裡面其中的一個年齡,進行訪問輸出
這時候我們就發現了一個問題,要是我們從外部傳入一個負數進來呢,這是不合邏輯的
其次我們就在person類中把age私有化
但是私有化卻只能在內類中訪問,外部無法訪問
我們就要在person類中建立一個訪問方法
一般來說,一個事物通常會對應兩個方法,一個set,一個get
但是這樣還是可以從外部呼叫訪問方法傳入一個負數進來
其實我們這樣做是為了可以在方法類中進行邏輯判斷語句,提高程式碼健壯性。
//封裝原則 classPerson { 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 因為優先訪問靜態程式碼塊,再訪問構造程式碼塊,最後建構函式帶引數的方法 } }