程式碼講解:面向物件下——程式碼塊、內部類、繼承(保證讓你全部都會噢)
阿新 • • 發佈:2018-11-13
//一、程式碼塊(筆試、面試常考知識點) //1.普通程式碼塊:普通程式碼塊就是定義在方法中的程式碼塊 // public class Lesson6{ // public static void main(String[] args){ // {//定義在main方法中的程式碼塊——》普通程式碼塊:可以讓同一個變數被兩次定義 // int num=1; // System.out.println("num="+num); // } // int num=3; // System.out.println("num="+num); // } // } //2.構造塊:與普通程式碼塊區別它是定義在類中的程式碼塊 // public class Lesson6{ // //構造塊先於構造方法執行,這樣將它寫在前面是為了暗示執行的順序;並且構造塊就像構造方法一樣每建立一個物件就會執行一次 // { // System.out.println("這是構造塊"); // } // public Lesson6(){ // System.out.println("這是構造方法"); // } // public static void main(String[] args){ // new Lesson6();//匿名物件 // new Lesson6();//匿名物件 // } // } //3.靜態程式碼塊:用static修飾的程式碼塊就叫靜態程式碼塊 //(1)在主類中:在主類中表示表示這個類含有main方法,即使程式的入口類,即是和檔名一樣的類,即是公有的那個類,即是編譯和執行的時 //候那個類名。 // public class Lesson6{ //靜態塊:靜態塊只能放在類中,不可以放在方法中,並且構造塊不管你建立幾個物件都只執行一次 //靜態塊之所以只執行一次是因為靜態塊是在JVM尋找要執行的位元組碼檔案(就是那個你進行編譯的檔案,它的檔名就是主類的檔名)的 //過程中就已經載入到虛擬機器了,它是屬於類的,所以在執行位元組碼檔案的時候就不會再執行靜態塊了,所以最後的執行結果是靜態塊在最最 //前面並且只執行一次。 // static{ // System.out.println("這是靜態塊"); // } // //構造塊 // { // System.out.println("這是構造塊"); // } // //構造方法 // public Lesson6(){ // System.out.println("這是構造方法"); // } // public static void main(String[] args){ // new Lesson6(); // new Lesson6(); // } // } //(2)在非主類中 //不管是在主類中還是在非主類中靜態塊的要求都是一樣的,並且執行順序都是一樣的。 //情況1: // class A{ // static{ // System.out.println("這是靜態塊"); // } // { // System.out.println("這是構造塊"); // } // public A(){ // System.out.println("這是構造方法"); // } // } // public class Lesson6{ // public static void main(String[] args){ // new A();//注意:main方法中執行的程式碼,建立的類一定是要和含有靜態塊的類是相關的,否則JVM將不會將靜態塊載入到JVM中,這樣的話 // //靜態塊就不會執行; // new A(); // } // } // //情況2: // class A{ // static{ // System.out.println("這是靜態塊"); // } // { // System.out.println("這是構造塊"); // } // public A(){ // System.out.println("這是構造方法"); // } // } // public class Lesson6{ // public static void main(String[] args){ // System.out.println("這是非主類中的主類");//這條語句和含有靜態塊的類完全沒有關係,所以不會將靜態塊載入到JVM所以不會執行 // } // } //4.同步程式碼塊(以後學) //二、內部類 //1.成員內部類 //成員內部類就像普通的內部類,在它的裡面可以以出現任何由static修飾的屬性或者方法; //情況1: // public class Lesson6{ // private String msg="這是外部類的私有屬性"; // class Inner{ // public Inner(){ // System.out.println("這是成員內部類"); // System.out.println(msg);//內部類可以直接訪問外部類的屬性,其實質相當於Lesson6.this.msg // } // // public void fun(){ // // Inner in = new Inner(); // // } // } // public static void main(String[] args){ // Lesson6.Inner inner=new Lesson6().new Inner();//非靜態內部類物件的建立必須依賴於外部類物件的建立,必須得外部類建立完物件 // //以後非靜態內部類才可以建立物件。而成員內部類屬於非靜態內部類所以它遵循非靜態 // //內部類建立物件的規則。 // } // } //情況2: // public class Lesson6{ // private String msg="這是外部類的私有屬性"; // class Inner{ // public Inner(){//從輸出結果可以看到構造方法先於普通方法執行 // System.out.println("這是成員內部類的構造方法"); // } // public void print(){ // System.out.println("這是成員內部類"); // System.out.println(msg);//內部類可以直接訪問外部類的屬性,其實質相當於Lesson6.this.msg // } // // public void fun(){ // // Inner in = new Inner(); // // } // } // public static void main(String[] args){ //成員內部類的類名:外部類.內部類 // Lesson6.Inner inner=new Lesson6().new Inner();//非靜態內部類物件的建立必須依賴於外部類物件的建立,必須得外部類建立完物件 // //以後非靜態內部類才可以建立物件。而成員內部類屬於非靜態內部類所以它遵循非 //靜態內部類建立物件的規則。但如果是在內部類裡面建立物件那麼就像普通類建立對 //象一樣 // inner.print(); //也可以通過方法呼叫來實現 // } // } //2.靜態內部類 //情況1:不可以訪問外部類的非靜態屬性 // class Outter{ // private String msg="這是外部類的私有屬性";//在本類以外的其他類中私有屬性需要訪問,那麼就需要封裝通過公有的方法來進行訪問 // public String getMsg(){ // return msg; // } // static class Inner{ // public Inner(){//只要建立內部類的物件就會執行這個無參構造 // System.out.println("這是靜態內部類的構造方法"); // } // public void print(){ // //在靜態內部類中不可以訪問外部類的非靜態屬性和非靜態方法 // System.out.println("這是靜態內部類"); // //System.out.println(msg);//相當於是Outter.this.msg//error:不可以訪問非靜態屬性 // } // } // public void fun(){ // //在外部類建立靜態內部類物件,不依賴外部類建立的物件; // //靜態內部類的類名是:外部類.內部類 // Outter.Inner inner=new Outter.Inner(); // inner.print(); // } // } // public class Lesson6{ // public static void main(String[] args){ // //建立一個外部類的物件訪問fun方法 // Outter out = new Outter(); // out.fun(); // } // } //情況2:將外部類的屬性改為靜態類那麼就可以在靜態內部類中訪問外部類的屬性 // class Outter{ // private static String msg="這是外部類的靜態私有屬性";//在本類以外的其他類中私有屬性需要訪問,那麼就需要封裝通過公有的方法來進行訪問 // public String getMsg(){ // return msg; // } // static class Inner{ // public Inner(){//只要建立內部類的物件就會執行這個無參構造 // System.out.println("這是靜態內部類的構造方法"); // } // public void print(){ // //在靜態內部類中不可以訪問外部類的非靜態屬性和非靜態方法,現在將外部類的屬性改為靜態屬性,那麼內部類就可以訪問了 // System.out.println("這是靜態內部類"); // System.out.println(msg);//相當於是Outter.this.msg // } // } // public void fun(){ // //在外部類建立靜態內部類物件,不依賴外部類建立的物件; // //靜態內部類的類名是:外部類.內部類 // Outter.Inner inner=new Outter.Inner(); // inner.print(); // } // } // public class Lesson6{ // public static void main(String[] args){ // //建立一個外部類的物件訪問fun方法 // Outter out = new Outter(); // out.fun(); // } // } //3.方法內部類 //在方法中的內部類,它與成員內部類相似,唯一的區別就是它的作用範圍僅僅在一個方法內 // class Outter{ // private String msg="這是外部類的私有屬性"; // public void print(int num){ // //這是外部類的一個方法,下面將內部類定義在這個方法當中,那麼它就叫做方法內部類,也叫做區域性內部類 // class Inner{ // public void fun(){ // System.out.println("這是一個方法內部類"); // System.out.println(msg);//在方法內部類裡面可以直接訪問外部類的私有屬性 // System.out.println(num); // } // } // Inner in=new Inner(); // in.fun();//這個只能在這個方法以內,如果超出方法那麼將無效 // } // } // public class Lesson6{ // public static void main(String[] args){ // //建立一個外部類的物件 // Outter out = new Outter(); // out.print(10);//呼叫外部類中包含內部類的方法,將內部類也執行了 // } // } //4.匿名內部類 //定義在方法中的沒有名字的內部類 //用匿名內部類實現和方法內部類一樣的功能 // interface MyInterfance{ // void test(); // } // class Outter{ // private String msg="這是外部類的私有屬性"; // public void print(int num){ // //下面建立一個匿名內部類,因為它實現了一個介面 // new MyInterfance(){//介面的實現 // public void test(){//方法重寫實現介面 // System.out.println("這是一個匿名內部類"); // System.out.println(msg); // System.out.println(num); // } // }.test();//直接呼叫內部類,因為它沒有名字不可以建立物件,如果不直接引用,那麼將不可以訪問了 // } // } // public class Lesson6{ // public static void main(String[] args){ // Outter out = new Outter(); // out.print(10); // } // } //三、繼承 //1.繼承的實現 // //情況1:父類的構造方法是無參構造 // class A{ // int num=10;//私有屬性 // String msg="這是A類的私有屬性"; // public A(){//A的無參構造方法 // System.out.println("這是A的無參構造方法"); // } // public void print(){ // System.out.print("這是A類的方法"); // } // } // class B extends A{ // public B(){//B的無參構造 // super();//在執行子類的構造方法之前必須先呼叫執行父類的構造方法;對於父類無參的構造方法會預設的呼叫 // System.out.println("這是子類的構造方法"); // } // public void fun(){ // System.out.println(num);//輸出的是父類的屬性//erro:私有屬性,不可以直接訪問 // System.out.println(msg);//error // } // } // public class Lesson6{ // public static void main(String[] args){ // B b=new B(); // b.fun(); // b.print();//呼叫父類的方法 // //注意執行的順序是:父類的構造方法先於子類的構造方法 // } // } //情況2:父類的構造方法全是含參構造並且有多個建構函式的時候,沒有無參構造了 //注意:在子類的構造方法中除了無參構造會預設呼叫意外,含參構造都不會預設呼叫,必須得自己手動呼叫,如果不呼叫父類的建構函式,那麼 //編譯就通過不了; // class A{ // int num;//私有屬性 // String msg; // public A(int num){//A的一個引數的含參構造方法 // System.out.println("這是A的一個引數的參構造方法"); // this.num=num; // } // public A(int num,String msg){//A的兩個引數的含參構造方法 // System.out.println("這是A的兩個引數的構造方法"); // this.num=num; // this.msg=msg; // } // public void print(){ // System.out.print("這是A類的方法"); // } // } // class B extends A{ // //error:因為B類是無參構造的話就不能將引數傳到super中,這樣的話是在沒有呼叫構造方法之前就引用了父類屬性會報錯說: // //無法在呼叫超類構造器(父類構造器)之前引用它的屬性 // // public B(){//B的無參構造 // // super(num,msg);//在執行子類的構造方法之前必須先呼叫執行父類的構造方法;由於沒有無參構造所以需要指明呼叫的構造方法 // // System.out.println("這是子類的構造方法"); // // } // public B(int num,String msg){ // super(num,msg);//在執行子類的構造方法之前必須先呼叫執行父類的構造方法;由於沒有無參構造所以需要指明呼叫的構造方法 // System.out.println("這是子類的構造方法"); // } // public void fun(){ // System.out.println(num);//輸出的是父類的屬性//erro:私有屬性,不可以直接訪問 // System.out.println(msg);//error // } // } // public class Lesson6{ // public static void main(String[] args){ // B b=new B(10,"這是A類的私有屬性"); // b.fun(); // b.print();//呼叫父類的方法 // //注意執行的順序是:父類的構造方法先於子類的構造方法 // } // } //2.繼承的限制 //對於私有屬性或者是私有方法的限制 //子類將繼承父類的所有結構,那麼私有屬性也會繼承,繼承的私有屬性是有訪問許可權的,不可以直接訪問,必須通過封裝的方法去訪問 // class A{ // private int num=10;//私有屬性,需要用封裝外部才可以訪問 // private String msg="這是A類的私有屬性"; // public int getNum(){ // return num; // } // public void setNum(int num){ // this.num=num; // } // public String getMsg(){ // return msg; // } // public void setMsg(String msg){ // this.msg=msg; // } // public A(){//A的無參構造方法 // System.out.println("這是A的無參構造方法"); // } // public void print(){ // System.out.print("這是A類的方法"); // } // } // class B extends A{ // public B(){//B的無參構造 // super();//在執行子類的構造方法之前必須先呼叫執行父類的構造方法;對於父類無參的構造方法會預設的呼叫 // System.out.println("這是子類的構造方法"); // } // public void fun(){ // //下面兩個語句每建立一次A類的物件都要執行一次構造方法 // System.out.println(new A().getNum());//輸出的是父類的屬性//erro:私有屬性,不可以直接訪問 // System.out.println(new A().getMsg());//error // } // } // public class Lesson6{ // public static void main(String[] args){ // B b=new B(); // b.fun(); // b.print();//呼叫父類的方法 // //注意執行的順序是:父類的構造方法先於子類的構造方法 // } // } // class Person{ // private String name; // private int age; // public String getName(){ // return name; // } // public int getAge(){ // return age; // } // public void setName(String name){ // this.name=name; // } // public void setAge(int age){ // this.age=age; // } // } // class Student extends Person{ // public void fun(){ // System.out.println(getName()); // } // } // public class Lesson6{ // public static void main(String[] args){ // Student stu = new Student(); // stu.setName("sdjd");//繼承的父類的方法 // //兩種方法輸出名字 // System.out.println(stu.getName()); // stu.fun(); // } // }