程式講解——JavaSE之面向物件程式設計—類於物件下
阿新 • • 發佈:2018-11-26
//javaSE面向物件程式設計——類於物件(下) //4.覆寫 //(1)方法的覆寫:首先方法的覆寫必須有繼承的關係,在子類中進行覆寫.在覆寫的時候還要求子類中進行覆寫的方法要比父 //類中的方法許可權更不為嚴格:public>protected>default>private //父類:public ——>子類:public ;父類:protacted——>子類:protected/public ; //父類:default——>子類:default/protected/public ; 父類:private——>子類看不見父類的方法,不可以進行方法覆寫 // class Person{ // public void print(){ // System.out.println("這是父類的方法"); // } // } // class Student extends Person{ // public void print(){//方法名、引數型別、引數個數、返回值型別相同 // System.out.println("這是子類經過覆寫以後的方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // new Person().print();//建立父類的物件並且呼叫經過覆寫以後的方法 // //從執行結果我們可以看出來,雖然print方法經過覆寫了,但是我們的父類呼叫這個方法的時候還是執行的它原來的內容 // new Student().print();//建立子類並且呼叫經過覆寫以後的方法 // //從執行結果可以看出來,經過覆寫以後子類的呼叫的這個方法就是覆寫以覆寫的方法 // } // } //錯誤的案例: // class Person{ // public void print(){ // System.out.println("這是父類的方法"); // } // } // class Student extends Person{ // void print(){//方法名、引數型別、引數個數、返回值型別相同(錯誤:用了比父類方法更為嚴格的訪問控制權限) // //會提示無法覆蓋父類的方法 // System.out.println("這是子類經過覆寫以後的方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // new Person().print();//建立父類的物件並且呼叫經過覆寫以後的方法 // //從執行結果我們可以看出來,雖然print方法經過覆寫了,但是我們的父類呼叫這個方法的時候還是執行的它原來的內容 // new Student().print();//建立子類並且呼叫經過覆寫以後的方法 // //從執行結果可以看出來,經過覆寫以後子類的呼叫的這個方法就是覆寫以覆寫的方法 // } // } //總結:方法的覆寫時,經過覆寫以後,父類建立的物件呼叫的方法還是未經過覆寫以後的方法,但是子類建立的物件呼叫的 //方法是經過覆寫以後的方法。 //(2)屬性的覆寫:當子類定義的名稱和父類名稱完全相同的時候就叫屬性覆寫 // class Person{ // String name="張三"; // public void print(){ // System.out.println(name); // } // } // class Student extends Person{ // String name="李四"; // } // public class Duotai{ // public static void main(String[] args){ // Student stu=new Student(); // System.out.println(stu.name); // } // } //(3)解釋過載與覆寫的區別 //方法重寫:方法重寫是方法名字相同,引數個數、引數型別、引數順序不同;一般來說返回值的型別是一樣的 //方法覆寫:方法覆寫是方法名字、引數個數、引數型別都相同,但是方法體不同即實現的函式功能不同叫做方法重寫 //(4)super關鍵字 //super表示父類的意思,所以可以通過super呼叫父類的方法,分別是以下兩種情況 //(4.1)super呼叫構造方法 //無參構造方法 // class Person{ // private String name; // public Person(){ // System.out.println("這是父類的構造方法"); // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // System.out.println("這是子類的構造方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Student stu=new Student(); // } // } //有參構造方法 // class Person{ // private String name; // //當父類中沒有了無參構造我們在子類裡面就需要表明我們需要呼叫哪個構造方法 // //如果父類在有多個構造方法,並且包含了無參構造我們也不可以不用指明呼叫哪個構造方法,系統會自動預設呼叫無參構造 // //(1)無參構造 // public Person(){ // System.out.println("這是父類的構造方法"); // } // //(2)含有一個引數的構造 // public Person(String name){ // System.out.println("這是父類含有一個引數的構造"); // this.name=name; // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(String name){ // //(1)super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // //(2)呼叫父類的含有一個引數的構造 // super(name);//name既可以是父類發私有屬性也可以是父類的狗狗有屬性,都可以訪問成功; // //重點在於我們需要知道在super的時候子類的構造方法也是需要含有這個引數的建構函式,在定義的時候就應該帶上這個 // //引數,不可以的是用super呼叫父類的含參構造方法的時候子類的構造方法為無參構造沒有給這個super傳參。 // System.out.println("這是子類的構造方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Student stu=new Student("張三"); // } // } //(4.2)super呼叫普通方法 // class Person{ // private String name; // public Person(){ // System.out.println("這是父類的構造方法"); // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // System.out.println("這是子類的構造方法"); // } // public void print(){ // super.print();//通過super呼叫父類的普通方法 // System.out.println("這是子類的普通方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Student stu=new Student(); // stu.print(); // } // } //5.final關鍵字 //(1)使用final修飾一個類 //final修飾的類不可以繼承 // //error // final class Person{ // private String name; // public Person(){ // System.out.println("這是父類的構造方法"); // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // System.out.println("這是子類的構造方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Student stu=new Student(); // } // } //(2)使用final修飾一個方法 //final修飾的方法不可以被覆寫 // //error // class Person{ // final public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // } // public void print(){ // System.out.println("這是子類覆寫以後的方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Student stu=new Student(); // } // } //對類和方法總結: //總結:為什麼final修飾完類、方法以後不可以繼承不可以覆寫,原因在於final表示不可以更改的意思,而我們的繼承和覆寫都表示在原有 //的基礎之上對它進行修改。所以是都不被允許的。 //(3)使用final定義常量 // public class Duotai{ // public static final int LEVEL_A=100;//注意在final定義常量必須在類中定義,相當於它是類的屬性,不是物件的屬性 // public static void main(String[] args){ // System.out.println("LEVEL_A="+LEVEL_A); // } // } //(4)分析下面這個程式: // byte b1=1,b2=2,b3,b6,b8; // final byte b4=4,b5=6,b7=9; // public void test() { // b3=(b1+b2); /*語句1*/ // b6=b4+b5; /*語句2*/ // b8=(b1+b4); /*語句3*/ // b7=(b2+b5); /*語句4*/ // System.out.println(b3+b6); // } // public class Duotai{ // byte b1=1,b2=2,b3,b6,b8; // final byte b4=4,b5=6,b7=9; // public void test() { // b3=(byte)(b1+b2); /*語句1*/ // //b1 b2看起來像是byte型,但是在給b3賦值的時候它程式還沒有執行,空間還沒有分配,這時候只會根據修飾這個變數的型別來看判斷這個變數 // //到底是什麼型別。所以在進行b3=(b1+b2);這條語句的時候相當於是將int賦值給了byte,大型別轉小型別程式自然不能通過。 // b6=b4+b5; /*語句2*/ // //正確,因為final修飾的變數它的型別不會改變,就算還沒有分配空間也會認為這個變數的型別是byte型 // b8=(byte)(b1+b4); /*語句3*/ // //錯誤:b1不是byte型別 // b7=(byte)(b2+b5); /*語句4*/ // //錯誤:b2不是byte型別 // System.out.println(b3+b6); // } // public static void main(String[] args){ // Duotai t=new Duotai(); // t.test(); // } // } //6.多型 //(1)向上轉型 // class Person{ // private String name; // public Person(){ // System.out.println("這是父類的構造方法"); // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // System.out.println("這是子類的構造方法"); // } // public void print(){//方法覆寫 // System.out.println("這是子類的普通方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // // Person per=new Person();//沒有向上轉型,雖然有方法覆寫,但是父類呼叫該方法的時候還是父類自己的方法 // // per.print(); // Person per=new Student();//向上轉型 // per.print(); // } // } //(2)向下轉型 // class Person{ // private String name; // public Person(){ // System.out.println("這是父類的構造方法"); // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // System.out.println("這是子類的構造方法"); // } // public void print(){//方法覆寫 // System.out.println("這是子類的普通方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Student stu=(Student)new Person();//向下轉型 // //向下轉型是將大型別轉換為小型別,需要強轉;強轉以後編譯可以通過,在語法層面來講沒有錯誤但是執行時候會出錯。 // stu.print(); // } // } //(3)通過instanceof實現轉型 // class Person{ // private String name; // public Person(){ // System.out.println("這是父類的構造方法"); // } // public void print(){ // System.out.println("這是父類的普通方法"); // } // } // class Student extends Person{ // public Student(){ // super();//呼叫父類的構造方法,這個是無參構造方法,如果不寫也會隱含的預設呼叫 // System.out.println("這是子類的構造方法"); // } // public void print(){//方法覆寫 // System.out.println("這是子類的普通方法"); // } // } // public class Duotai{ // public static void main(String[] args){ // Person per=new Student();//先實現向上轉型 //為什麼下面兩個語句都是true? // System.out.println(per instanceof Person);//true // System.out.println(per instanceof Student);//true // if(per instanceof Student){ // Student stu=(Student)per;//要實現向下轉型必須先實現向上轉型,所以我們的判斷條件是是否有實現向上轉型 // stu.print(); // } // } // }