亚洲中字慕日产2020,大陆极品少妇内射AAAAAA,无码av大香线蕉伊人久久,久久精品国产亚洲av麻豆网站

資訊專欄INFORMATION COLUMN

Java基礎:Java核心技術(shù)提示的易忽略點 Ch6

Chaz / 2281人閱讀

摘要:內(nèi)部類就是這樣一個情況,內(nèi)部類的出現(xiàn)雖然在運行時會被拆分為獨立的臨時類,但是在代碼層面加深了對代碼的理解難度,所以很難說其優(yōu)弊殊勝。

Core Java Volume 1 Key Points chap6 接口和抽象類的概念

接口和抽象類是Java繼承鏈的基礎,其區(qū)別也較為明顯,在Java語言的設計中,允許接口的多實現(xiàn),但不允許抽象類的多繼承,這樣做符合簡潔明了的面向?qū)ο笤O計思路:也就是說類只可以簡單地擁有唯一父模型(抽象類),但是可以擁有多種不同的特征(接口),這樣的設計大大簡化了Java的面向?qū)ο筮壿嫛?/p>

除此之外呢,它們還有這樣的區(qū)別:
接口為了保證其描述特征的特性,只允許描述成員方法的特征(返回值、方法名、參數(shù)),不對成員方法做具體實現(xiàn),而且在接口內(nèi)部不允許使用私有屬性和方法,究其根本,都是因為作為描述特征的接口不應該具有個性化的屬性和方法;而抽象類像類一樣,沒有這樣的限制,但是一般使用缺省的方法來統(tǒng)一定義模型的方法,所以方法體要么是空,要么是通用性較高的默認情況。

另外,在編碼風格上,我們應該盡量給接口起名為形容詞或副詞,以貼近其是對類特征描述的本質(zhì),在JDK中這樣的風格處處可見,比如大多數(shù)的接口會被以able結(jié)尾以說明實現(xiàn)這樣的接口可以獲得某些能力,比如實現(xiàn)Comparable接口可以獲得被比較的能力,進而在對象數(shù)組中可以使用Arrays.sort方法來排序。而抽象類像類一樣使用名詞來定名,另外可以在尾部加上諸如helper,handler來說明其作用。

克隆

clone是Object這一通用父類的方法,這個方法是protected類型的,因此在用戶編寫的代碼里是不能直接使用的。這個方法的目的為了實現(xiàn)對象的克隆,理論上講,也就是復制一份完全相同的對象給我們使用。剛剛說了由于它是protected類型的,因此需要在我們使用的需要拷貝的對象的類里重寫這個方法并把權(quán)限設為public的才行,不僅如此,為了類型檢查的原因,我們還需要實現(xiàn)Cloneable這個marker接口(無方法接口)。這樣做顯然很繁瑣,而且由于淺拷貝的問題,還很容易出錯,因為很有可能拷貝出的新對象中某些子對象不是拷貝而仍然是引用。下面是個這樣的例子:

class Email implements Cloneable{
    private String info;
    public Email(String info) {
        this.info = info;
    }
    
    public String getInfo() {
        return info;
    }
    public void setInfo(String info) {
        this.info = info;
    }
    @Override
    protected Object clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        return super.clone();
    }
}
class People implements Cloneable {
    private String name;
    private Email mail;
    
    
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public Email getMail() {
        return mail;
    }
    public void setMail(Email mail) {
        this.mail = mail;
    }
    
    @Override
    public String toString() {
        return "People [name=" + name + ", mail=" + mail.getInfo() + "]";
    }
    @Override
    public People clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        People people = (People) super.clone();
        return people;
    }
}
public class JustTest {
    public static void main(String[] args) throws InterruptedException {
        People people1 = new People();
        people1.setName("xiaoming");
        people1.setMail(new Email("xm@gmail.com"));
        People people2 = new People();
        try {
            people2 = (People) people1.clone();
            System.out.println(people1);
            System.out.println(people2);
            System.out.println("--------------------------------------");
            people1.getMail().setInfo("hi@gmail.com");
            System.out.println(people1);
            System.out.println(people2);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

run:

People [name=xiaoming, mail=xm@gmail.com]
People [name=xiaoming, mail=xm@gmail.com]
--------------------------------------
People [name=xiaoming, mail=hi@gmail.com]
People [name=xiaoming, mail=hi@gmail.com]

這就是淺拷貝帶來的問題,直接使用父類定義的clone就是會有這樣的問題。

所以需要再重寫的clone方法里對這樣的問題進行修改:

@Override
    public People clone() throws CloneNotSupportedException {
        // TODO Auto-generated method stub
        People people = (People) super.clone();
        //people.setMail((Email) mail.clone());
        return people;
    }
內(nèi)部類

在面向?qū)ο笙到y(tǒng)中,我們的類是對象的模板,接口表示類的特征,每個類擁有自己的成員變量和成員方法,對象擁有自己所屬類的成員變量和成員方法,對象之間互相調(diào)用,通過方法來實現(xiàn)信息溝通并執(zhí)行相應的功能。一切在運行時層面上其實就是這樣,我們在代碼層面可以保持和運行時層面相同的編碼規(guī)則,這樣做可以使得代碼簡潔有力,在編寫和運行的過程中保持一致性。然而事實是任何一門語言都會在代碼層面加入一些特性,注入語法特性,使得編碼看起來更緊湊、編寫更簡單,但是破壞了這種代碼層面和運行時層面的一致性。內(nèi)部類就是這樣一個情況,內(nèi)部類的出現(xiàn)雖然在運行時會被拆分為獨立的臨時類,但是在代碼層面加深了對代碼的理解難度,所以很難說其優(yōu)弊殊勝。

下面是個最簡單的說明其用法的例子:

public class Outer {
    private String info="hello world";
    public class Inner{
        public void func(){
            System.out.println(info);
        }
    }
    public static void main(String[] args) {
        Outer outer = new Outer();
        Inner inner = outer.new Inner();
        inner.func();
    }
}

這個例子我們可以看出來,這里的內(nèi)部類可以“看做”是Outer的一個成員,所以這樣寫就的內(nèi)部類也叫作成員內(nèi)部類,成員內(nèi)部類可以直接使用外部類的成員和方法,而外部類則需要構(gòu)造內(nèi)部類的對象才能使用內(nèi)部類。之所以說是“看做”,是因為在實際運行時內(nèi)部類會被編譯成一個臨時類而脫離外部類,我們可以試試看:

$ javac Outer.java

編譯后可以得到兩個class文件:Outer.class和Outer$Inner.class,后者就是拆分好了的內(nèi)部類class,所以在運行時可以使其和一般情況一樣。
我們進一步分析其真身:

$ javap Outer
    Compiled from "Outer.java"
    public class Outer extends java.lang.Object{
        public Outer();
        public static void main(java.lang.String[]);
        static java.lang.String access$000(Outer);
    }

$ javap Outer$Inner
Compiled from "Outer.java"
public class Outer$Inner extends java.lang.Object{
    final Outer this$0;
    public Outer$Inner(Outer);
    public void func();
}

我們可以看到內(nèi)部類的臨時獨立生成類的初始化方法中帶有外部類類型的參數(shù),這樣就能夠保證內(nèi)部類可以完整訪問外部類成員變量和成員方法。

那么我們?yōu)槭裁匆褂眠@種看起來就不清不楚的內(nèi)部類呢?我的理解是有些類實際上非常簡單,多帶帶列出對整個系統(tǒng)意義不大,而且和某些類關(guān)系非常大,所以就直接把這個類放入和其關(guān)系大的類之中以形成內(nèi)部類,這樣在代碼層面看起來更加簡潔,但也不影響運行時的正確性。

除了上述的成員內(nèi)部類外,還有局部內(nèi)部類(內(nèi)部類位于方法體內(nèi),這種內(nèi)部類的作用域僅限于方法內(nèi)部)、匿名內(nèi)部類(不對內(nèi)部類進行顯式定義而直接在使用時順帶定義),但是無論是哪一種,其運行時都會被獨立拆分并像一般情況那樣運行。

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/65511.html

相關(guān)文章

  • Java基礎Java核心技術(shù)提示的易忽略 Ch4

    摘要:所以,在讀的核心技術(shù)的過程中,我記錄下這些所謂的易忽略的問題,這些問題將會持續(xù)更新在我的這個的博客下,也算是激勵自己重新挖掘這些基礎問題的內(nèi)涵。類路徑只是讓能夠通過配置好的全路徑名找到所需的外部類。 開篇Java是一門不那么簡單也不那么復雜的語言,Java里面有很多問題和特性是容易被使用者忽視的,這些問題也許會難住新手,同時也許會是老手不小心跌入的無故之坑,只有精于對基礎的提煉才能最大...

    ytwman 評論0 收藏0
  • Java基礎Java核心技術(shù)提示的易忽略 Ch5

    摘要:而并不是父類對象的引用,而只是給編譯器的一個提示性質(zhì)的標志?;蛘咦远x的提示在編譯的時候使用當前子類的父類定義的構(gòu)造器去初始化當前對象。所以,總結(jié)起來,的用法歸為兩種一是可以調(diào)用父類構(gòu)造器,二是可以調(diào)用父類方法。 開篇Java是一門不那么簡單也不那么復雜的語言,Java里面有很多問題和特性是容易被使用者忽視的,這些問題也許會難住新手,同時也許會是老手不小心跌入的無故之坑,只有精于對基礎...

    weapon 評論0 收藏0
  • 從零開始學 Kotlin 之「2」數(shù)據(jù)類型

    摘要:前言大家好,這里是從零開始學之數(shù)據(jù)類型,本文首發(fā)于公眾號,歡迎前往大家關(guān)注。輸出布爾類型中的布爾類型用表示,它的值有和。若需要可空引用時,布爾類型的值會被裝箱。此時程序會拋出異常最后從零開始學之數(shù)據(jù)類型到這里就結(jié)束了。 前言 大家好,這里是「從零開始學 Kotlin 之『2 』數(shù)據(jù)類型」,本文首發(fā)于公眾號「Binguner」,歡迎前往大家關(guān)注。我會每周分享一些關(guān)于 Android 和...

    Awbeci 評論0 收藏0
  • Java 征途:行者的地圖

    摘要:老實說,當時一進入世界的大門就暈了,各種規(guī)范概念和英文縮寫詞能把人整的暈暈乎乎。等新的英文縮寫又出現(xiàn)了,一口老血還沒來得及噴出,又重新振作開始新的學習征程。 showImg(http://upload-images.jianshu.io/upload_images/1131767-1c5d16e39435df10.jpg?imageMogr2/auto-orient/strip%7Ci...

    dkzwm 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<