日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

ThinkJava-复用类

發布時間:2025/3/20 java 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 ThinkJava-复用类 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
7 .2 繼承語法 例子: package com.cy.reusing;import static com.java.util.Print.*;class Cleanser {private String s = "Cleanser";public void append(String a) { s += a; }public void dilute() { append(" dilute()"); }public void apply() { append(" apply()"); }public void scrub() { append(" scrub()"); }public String toString() { return s; }public static void main(String[] args) {Cleanser x = new Cleanser();x.dilute(); x.apply(); x.scrub();print(x);} } public class Detergent extends Cleanser {// Change a method:public void scrub() {append(" Detergent.scrub()");super.scrub(); // Call base-class version }// Add methods to the interface:public void foam() { append(" foam()"); }// Test the new class:public static void main(String[] args) {Detergent x = new Detergent();x.dilute();x.apply();x.scrub();x.foam();print(x);print("Testing base class:");Cleanser.main(args);} } /* Output: Cleanser dilute() apply() Detergent.scrub() scrub() foam() Testing base class: Cleanser dilute() apply() scrub() *///:~ View Code Cleanser中所有的方法都必須是public的,這一點非常重要。請記住,如果沒有加任何訪問 權限修飾詞,那么成員默認的訪問權限是包訪問權限, 它僅允許包內的成員訪問。因此,在此 包中,如果沒有訪問權限修飾詞,任何人都可以使用這些方法。例如, Detergent就不成問題。 但是,其他包中的某個類若要從CIeanser中繼承,則只能訪問public成員。所以,為了繼承, 一 般的規則是將所有的數據成員都指定為private ,將所有的方法指定為public (稍后將會學到, protected成員也可以借助導出類來訪問)。當然,在特殊情況下,必須做出調整,但上述方法的 確是一個很有用的規則。 正如我們在scrub()中所見,使用基類中定義的方法及對它進行修改是可行的。在此例中, 你可能想要在新版本中調用從基類繼承而來的方法。但是在scrub()中,并不能直接調用scrub() , 因為這樣做將會產生遞歸,而這并不是你所期望的。為解決此問題, Java用super關鍵字表示超 類的意思,當前類就是從超類繼承來的。為此,表達式super.scrub()將調用基類版本的scrub() 方法. 7.8 final關鍵字 7.8.1 final 數據 一個既是static又是final的域只占據一段不能改變的存儲空間。 當對對象引用而不是基本類型運用final時, 其含義會有一點令人迷惑。對于基本類型, final使數值恒定不變; 而用于對象引用, final使引用恒定不.變。一旦引用被初始化指向一個對 象,就無法再把它改為指向另一個對象。然而,對象其自身卻是可以被修改的, Java并未提供 使任何對象恒定不變的途徑(但可以自己編寫類以取得使對象恒定不變的效果)。這一限制同樣 適用數組,它也是對象。 fínal 參數: Java允許在參數列表中以聲明的方式將參數指明為final。這意味著你無法在方法中更改參數 引用所指向的對象: package com.cy.reusing;class Gizmo {public void spin() {} }public class FinalArguments {void with(final Gizmo g) {//! g = new Gizmo(); // Illegal -- g is final }void without(Gizmo g) {g = new Gizmo(); // OK -- g not final g.spin();}// void f(final int i) { i++; } // Can't change// You can only read from a final primitive:int g(final int i) { return i + 1; }public static void main(String[] args) {FinalArguments bf = new FinalArguments();bf.without(null);bf.with(null);} } ///:~ View Code 方法f()和g()展示了當基本類型的參數被指明為final時所出現的結果:你可以讀參數,但卻 無法修改參數.這一特性主要用來向匿名內部類傳遞數據,我們將在第10章中學習它. 7.8.2 final 方法 使用final方法的原因有兩個.第一個原因是把方法鎖定,以防任何繼承類修改它的含義. 這是出于設計的考慮:想要確保在繼承中使方法行為保持不變,并且不會被覆蓋。 過去建議使用final方法的第二個原因是效率。 類中所有的private方法都隱式地指定為是final的。由于無法取用private方法,所以也就無 法覆蓋它.可以對private方法添加final 修飾詞,但這并不能給該方法增加任何額外的意義。 這一問題會造成混淆.因為,如果你試圖覆蓋一個private方法(隱含是final的) ,似乎是奏 效的,而且編譯器也不會繪出錯誤信息: package com.cy.reusing;import static com.java.util.Print.*;class WithFinals {// Identical to "private" alone:private final void f() { print("WithFinals.f()"); }// Also automatically "final":private void g() { print("WithFinals.g()"); } }class OverridingPrivate extends WithFinals {private final void f() {print("OverridingPrivate.f()");}private void g() {print("OverridingPrivate.g()");} }class OverridingPrivate2 extends OverridingPrivate {public final void f() {print("OverridingPrivate2.f()");}public void g() {print("OverridingPrivate2.g()");} }public class FinalOverridingIllusion {public static void main(String[] args) {OverridingPrivate2 op2 = new OverridingPrivate2();op2.f();op2.g();// You can upcast:OverridingPrivate op = op2;// But you can't call the methods://! op.f();//! op.g();// Same here:WithFinals wf = op2;//! wf.f();//! wf.g(); } } /* Output: OverridingPrivate2.f() OverridingPrivate2.g() *///:~ View Code "覆蓋"只有在某方法是基類的接口的一部分時才會出現。即,必須能將一個對象向上轉型 為它的基本類型并調用相同的方法(這一點在下一章闡明)。 如果某方法為prlv?te ,它就不是基 類的接口的一部分。它僅是一些隱藏于類中的程序代碼,只不過是具有相同的名稱而已。但如 果在導出類中以相同的名稱生成-個publlc 、protected或包訪問權限方法的話,該方法就不會產 生在基類中出現的"僅具有相同名稱"的情況。此時你并沒有覆蓋該方法,僅是生成了一個新 的方法。由于private方法無法觸及而且能有效隱藏,所以除了把它看成是因為它所歸屬的類的 組織結構的原因而存在外,其他任何事物都不需要考慮到它。 7.8.3 final 類 當將某個類的整體定義為final時(通過將關鍵字final置于它的定義之前), -就表明了你不打 算繼承該類,而且也不允許別人這樣傲。換句話說,出于某種考慮,你對該類的設計永不需要 做任何變動,或者出于安全的考慮,你不希望它有子類。 package com.cy.reusing;class SmallBrain {}final class Dinosaur {int i = 7;int j = 1;SmallBrain x = new SmallBrain();void f() {} }//! class Further extends Dinosaur {} // error: Cannot extend final class 'Dinosaur'public class Jurassic {public static void main(String[] args) {Dinosaur n = new Dinosaur();n.f();n.i = 40;n.j++;} } ///:~ View Code 請注意, final類的域可以根據個人的意愿選擇為是或不是final。不論類是否被定義為final , 相同的規則都適用于定義為final的域。然而,由于final類禁止繼承,所以final類中所有的方法 都隱式指定為是final的,因為無法覆蓋色們。在final類中可以給方法添加final修飾詞,但這不 會增添任何意義。 7.9 初始化及類的加載 7.9. 1 繼承與初始化 了解包括繼承在內的初始化全過程,以對所發生的一切有個全局性的把握,是很有益的。 請看下例: package com.cy.reusing;import static com.java.util.Print.*;class Insect {private int i = 9;protected int j;Insect() {print("i = " + i + ", j = " + j);j = 39;}private static int x1 = printInit("static Insect.x1 initialized");static int printInit(String s) {print(s);return 47;} }public class Beetle extends Insect {private int k = printInit("Beetle.k initialized");public Beetle() {print("k = " + k);print("j = " + j);}private static int x2 = printInit("static Beetle.x2 initialized");public static void main(String[] args) {print("Beetle constructor");Beetle b = new Beetle();} } /* Output: static Insect.x1 initialized static Beetle.x2 initialized Beetle constructor i = 9, j = 0 Beetle.k initialized k = 47 j = 39 *///:~ 在Beetle上運行Java時,所發生的第-件事情就是試圖訪問Bettle.main() (一個static方法) , 于是加載器開始啟動并找出Beetle類的編譯代碼(在名為BattIe.class的文件之中)。在對它進行 加載的過程中,編譯器注意到它有一個基類(這是由關鍵字extends得知的) .于是它繼續進行加 載。不管你是否打算產生一個該基類的對象,這都要發生(請嘗試將對象創建代碼注釋掉,以 證明這一點)。 如果該基類還有其自身的基類,那么第二個基類就會被加載,如此類推。接下來,根基類 中的static初始化(在此例中為Insect) 即會被執行,然后是下一個導出類,以此類推。這種方 式很重要,因為導出類的static初始化可能會依賴于基類成員能否被正確初始化。 至此為止,必要的類都已加載完畢,對象就可以被創建了。首先,對象中所有的基本類型 都會被設為默認值,對象引用被設為null——這是通過將對象內存設為二進制零值而一舉生成的。 然后,基類的構造器會被調用。在本例中,它是被自動調用的。但也可以用super來指定對基類 構造器的調用(正如在Beetle()構造器中的第一步操作)。基類構造器和導出類的構造器一樣, 以相同的順序來經歷相同的過程。在基類構造器完成之后,實例變量按其次序被初始化。最后, 構造器的其余部分被執行。 ----------------

轉載于:https://www.cnblogs.com/tenWood/p/8411979.html

總結

以上是生活随笔為你收集整理的ThinkJava-复用类的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。