標籤:代碼 類的方法 執行個體 new 並且 存在 載入 alt 建立
為什麼要使用繼承?
繼承的好處:
(1)抽取出了重複的代碼,使代碼更加靈活
(2)建立了類和類之間的聯絡
繼承的缺點:
耦合性太強
在OC中的繼承是:
1、OC中不允許子類和父類擁有相同名稱的成員變數名;(java中是可以的)
2、編譯器從上往下執行,所以在子類前面至少應該要有父類的聲明;如
@interface Worker : Person @end
3、OC中的子類可以擁有和父類相同名稱的方法,在子類調用時,優先去自己的內部尋找,如果父類沒有定義該方法,則繼續在繼承鏈上尋找,直到找到為止,如果找到NSobject為止仍然未找到,則報錯;
4、子類允許重寫父類的方法,在調用子類對象的重寫方法時,就會調用重寫後的方法;(與java中子類重寫父類中的非靜態方法是一樣的)
5、如果在子類中 需要調用父類的功能,可以藉助super關鍵字(與java一樣)。
在java中的繼承是:
注意:靜態代碼塊不管建立多少個對象只執行一次,非靜態代碼塊隨著對象的建立而執行,並且總是在構造方法的前面執行。
1、父類的靜態代碼塊—>子類的靜態代碼塊—>主方法(執行哪個程式就執行哪個程式的主方法)—>父類的非靜態代碼塊—>父類的無參建構函式—>子類的非靜態代碼塊—>子類的無參建構函式(若實際子類執行的是有參建構函式,則不執行無參建構函式)—>成員函數(指的是非靜態方法)(指定執行哪個就執行哪個成員函數,若重寫了父類成員函數,則只執行子類的成員函數)
在多態的時候為什麼重寫父類的靜態方法不會不這調用父類的靜態方法,而子類重寫父類的非靜態方法後就調用的是子類的非靜態方法?
先看代碼:
1 class SuperClass{ 2 //靜態方法 3 public static void staticMethod(){ 4 System.out.println("SuperClass: inside staticMethod"); 5 } 6 //非靜態方法 7 public void method(){ 8 System.out.println("SuperClass: inside method"); 9 }10 }11 12 class SubClass extends SuperClass{13 14 //overriding the static method15 public static void staticMethod(){16 System.out.println("SubClass: inside staticMethod");17 }18 //overriding the method19 public void method(){20 System.out.println("SubClass: inside method");21 }22 }23 public class a24 {25 public static void main(String []args){26 27 SuperClass superClass = new SuperClass(); //父類自身28 SuperClass subClass1 = new SubClass(); //多態29 SubClass subClass2 = new SubClass(); //子類自身30 31 superClass.staticMethod();32 subClass1.staticMethod();33 subClass1.method();34 subClass2.staticMethod();35 36 } 37 }
運行結果:
注意第二行的輸出結果,如果是重寫靜態方法的話,第二行的和第三行的結果是相同的。雖然就算你重寫靜態方法,編譯器也不會報錯,本質上這並不是重寫,是你個人認為重寫了而已,也就是說,如果你試圖重寫靜態方法,Java不會阻止你這麼做,但你卻得不到預期的結果(重寫僅對非靜態方法有用)。重寫指的是根據運行時對象的類型來決定調用哪個方法,而不是根據編譯時間的類型。讓我們猜一猜為什麼靜態方法是比較特殊的?因為它們是類的方法,所以它們在編譯階段就使用編譯出來的類型進行綁定了。使用對象引用來訪問靜態方法只是Java設計者給程式員的自由。我們應該直接使用類名來訪問靜態方法,而不要使用對象引用來訪問。而父類的非靜態方法與子類的非靜態方法名相同(包括參數),那才叫做重寫,因為他們訪問的是同一個記憶體空間,靜態記憶體空間請看下面。
我們得知道static在記憶體是怎麼存放的?
一個類的靜態方法和靜態變數使用原理,JVM會把類的這個靜態方法和靜態變數在類載入的過程中讀入記憶體(事實上是方法區),相當於常駐記憶體。也叫做類載入,static 修飾的 在JVM運行時就載入到記憶體中了 所以不需要執行個體類
大家都知道,在程式中任何變數或者代碼都是在運行時由系統自動分配記憶體來儲存的,而所謂靜態就是指在第一次分配記憶體後,所分配的記憶體會一直存在,直到程式退出記憶體才會釋放這個空間,也就是只要程式在運行,那麼這塊記憶體就會一直存在。這樣做有什麼意義呢? 在Java程式裡面,所有的東西都是對象,而對象的抽象就是類,對於一個類而言,如果要使用他的成員,那麼普通情況下必須先執行個體化對象後,通過對象的引用才能夠訪問這些成員,但是有種情況例外,就是該成員是用static聲明的(在這裡所講排除了類的存取控制),因為static修飾的方法在編譯時間就進行靜態繫結了,每個靜態方法都在不同的記憶體空間,所以還是調用父類的靜態方法。
結論:
1、OC中的繼承是先到子類中找,找不到再到父類中找。
2、java中的繼承是先到父類中找,找不到再到子類中找。
java中的繼承與oc中的繼承的區別