優(yōu)雅編程之這樣使用類和接口,你就“正?!绷耍ㄈ?/h1>

開心一笑

【懸崖上一只小老鼠揮舞著短短的前爪,一次又一次跳下去,努力學習飛翔,旁邊母蝙蝠看著它摔的頭破血流,憂心的說:它爹,要不告訴它,它不是咱親生的!】

**提出問題******

項目中如何使用類和接口???

解決問題

使類和成員的可訪問性最小化

要區(qū)別設計良好的模塊與設計不好的模塊,最重要的因素在于,這個模塊對于外部的其他模塊而言,是否隱藏其內(nèi)部數(shù)據(jù)和其他實現(xiàn)細節(jié)。

第一原則很簡單:盡可能地使每個類或者成員不被外界訪問。換句話說,應該使用與你正在編寫的軟件的對于功能相一致的,盡可能最小的訪問級別。

對于頂級的類和接口,只有兩種可能的訪問級別:包級私有的(package-private)和公有的(public)。

對于成員,有四種訪問級別,具體的就不說了。

實例域決不能是公有的,特別是指向一個可變對象的。

例如:
//錯誤的
public static final Thing[] VALUES = { ... }

解決方法:

private static final Thing[] PRIVATE_VALUES = { .... }

public static final List<Thing> VALUES = Collections.unmodifiableList(Arrays.asList(PRIVATE_VALUES));

另一種解決方法是:添加一個公有方法,返回私有數(shù)組的一個備份:

private static final Thing[] PRIVATE_VALUES = { .... }

public static final Thing[] values(){
    return PRIVATE_VALUES.clone();
}

總而言之,你應該始終盡可能地降低可訪問性。除了公有靜態(tài)final域的特殊情形之外,公有類都不應該包含公有域。并且要確保公有靜態(tài)final域所引用的對象都是不可以變得。

在公有類中使用訪問方法而非公有域

錯誤的:

class Point{
    public double x;
    public double y;

}

正確的:

class Point{

    private double x;
    private double y;

    public Point(double x, double y) {
        this.x = x;
        this.y = y;
    }

    public double getX() {
        return x;
    }

    public void setX(double x) {
        this.x = x;
    }

    public double getY() {
        return y;
    }

    public void setY(double y) {
        this.y = y;
    }
}

總而言之,公有類永遠都不應該暴露可變得域,雖然還是有問題,但是讓公有類暴露不可變得域其危害性比較小。

使可變性最小

為了使類成為不可變,要遵循下面5條規(guī)則:

  • 不要提供任何會修改對象狀態(tài)的方法
  • 保證類不會被擴展(做法:讓類成為final類型)
  • 使所有的域都是final的
  • 使所有的域都成為私有的
  • 確保對于任何可變組件的互斥訪問

不可變對象優(yōu)點:

  • 不可變對象比較簡單
  • 不可變對象本質(zhì)上是線程安全的,它們不要求同步。
  • 不可變對象可以被自由分享
復合優(yōu)先于繼承

不用擴展現(xiàn)有的類,而是在新的類中增加一個私有域,它引用現(xiàn)有類的一個實例。這種設計稱做“復合”。

總結(jié):繼承的功能非常強大,但是也存在很多問題,因為它違背了封裝原則。只有當子類和超類之間確實存在子類型關(guān)系時,使用繼承才是恰當?shù)?。即使如此。如果子類和超類處在不同的包中,并且超類并不是為了繼承而設計的,那么繼承將會導致脆弱性。為了避免這種脆弱性,可以用復合和轉(zhuǎn)發(fā)機制來代替繼承,尤其是但存在適當?shù)慕涌诳梢詫崿F(xiàn)包裝類的時候。包裝類不僅比子類更加健壯,而且功能也更加強大。

具體例子可以看《Effective Java》書中的例子。

要么為繼承而設計,并提供文檔說明,要么就禁止繼承

關(guān)于程序文檔有句格言:好的API文檔應該描述一個給定的方法做了什么工作,而不是描述它是如何做到的。

標題說的挺明確的,用的比較少,具體就不多說明了。

接口優(yōu)于抽象類
類層次優(yōu)于標簽類

例如下面是一個標簽類:

class Figure{
    enum Shape{RECTANGLE,CIRCLE}

    final Shape shape;

    double length;
    double width;

    double radius;

    Figure(double radius){
        shape = Shape.CIRCLE;
        this.radius = radius;
    }

    Figure(double length,double width){
        shape = Shape.RECTANGLE;
        this.length = length;
        this.width = width;
    }

    double area(){
        switch (shape){
            case RECTANGLE:
                return length * width;
            case CIRCLE:
                return Math.PI * (radius * radius);
            default:
                throw new AssertionError();
        }
    }
}

標簽類過于冗長,容易出錯,并且效率低下。

改正后的代碼,下面是類層次:

abstract class Figure{

abstract double area();
}

class Circle extends Figure{
    final double radius;

    Circle(double radius){ this.radius = radius;}

    double area(){ return  Math.PI * (radius * radius);}
}

class Rectangle extends Figure{
    final double length;
    final double width;

    Rectangle(double length,double width){
        this.length = length;
        this.width = width;
    }

    double area(){ return length * width;}
}
用函數(shù)對象表示策略

感覺工作用的比較少,具體可以看書本例子。

接口只用于定義類型

當類實現(xiàn)接口時,接口就充當可以引用這個類的實例的類型。因此,類實現(xiàn)類接口,就表明客戶端可以對這個類的實例實施某些動作。為了任何其他目的而定義接口是不恰當?shù)摹?/strong>

常量接口:接口沒有包含任何方法,它只包含靜態(tài)final域。

public interface ObjectStreamConstants {

    /**
     * Magic number that is written to the stream header.
     */
    final static short STREAM_MAGIC = (short)0xaced;

    /**
     * Version number that is written to the stream header.
     */
    final static short STREAM_VERSION = 5;

    /* Each item in the stream is preceded by a tag
     */
}

常量接口模式是對接口的不良使用。

解決方案:

如果這些常量與某個現(xiàn)有的類或者接口緊密相關(guān),就應該把這些常量添加到這個類或者接口中。

簡而言之,接口應該只被用來定義類型,它們不應該被用來導出常量。

優(yōu)先考慮靜態(tài)成員類

嵌套類:是指被定義在另一個類的內(nèi)部的類。嵌套類有四種:靜態(tài)成員類,非靜態(tài)成員類,匿名類和局部類,除了第一種之外,其他三種都被稱為內(nèi)部類。

總結(jié):如果一個嵌套類需要在單個方法之外仍然是可見的,或者它太長了,不適合于放在方法內(nèi)部,就應該使用成員類。如果成員類的每個實例都需要一個指向其外圍實例的引用,就要把成員類做成非靜態(tài)的;否則做成靜態(tài)的。假設這個嵌套類屬于一個方法的內(nèi)部,如果你只需要在一個地方創(chuàng)建實例,并且已經(jīng)有了一個預置的類型可以說明這個類的特征,就要把它做成匿名類;否則,就做成局部類。

讀書感悟

來自亦舒《嘆息橋》

  • 做不到是你自己的事,午夜夢回,你愛怎么回味就怎么回味,但人前人后,我要你裝出什么都沒有發(fā)生過的樣子。你可以的,我們都可以,人都是這般活下來的。
  • 人生就像一座橋,我們從彼處來,往那邊去,一邊走一邊不住嘆息,因恨事太多。
  • 這是我廿一年生命中前所未有的感覺,我高興到極限,耳邊有奇異的嗡嗡聲,內(nèi)心漲漲地飽滿,十分難以形容,但是,我沒有笑,我竟想哭,要盡很大的努力才把眼淚留在眼眶內(nèi)。發(fā)生了什么事?
  • 沒有人愛我,會比你愛我更多。

其他

如果有帶給你一絲絲小快樂,就讓快樂繼續(xù)傳遞下去,歡迎轉(zhuǎn)載,點贊,頂,歡迎留下寶貴的意見,多謝支持!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者

  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,250評論 6 530
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 97,923評論 3 413
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事。” “怎么了?”我有些...
    開封第一講書人閱讀 175,041評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經(jīng)常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,475評論 1 308
  • 正文 為了忘掉前任,我火速辦了婚禮,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,253評論 6 405
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 54,801評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 42,882評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 42,023評論 0 285
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 48,530評論 1 331
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 40,494評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,639評論 1 366
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,177評論 5 355
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 43,890評論 3 345
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,289評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,552評論 1 281
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,242評論 3 389
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,626評論 2 370

推薦閱讀更多精彩內(nèi)容

  • 類與接口是Java語言的核心,設計出更加有用、健壯和靈活的類與接口很重要。 13、使類和成員的可訪問性最小化 設計...
    Alent閱讀 683評論 0 2
  • 1.使類和成員的可訪問性最小化 訪問修飾符: private protected public 頂層的(非嵌套)類...
    666真666閱讀 847評論 0 1
  • 類和接口 一、使類和成員的可訪問性最小化 首先我們要了解一個 軟件設計基本原則:封裝 模塊隱藏所有的實現(xiàn)細節(jié),只通...
    dooze閱讀 491評論 0 0
  • 一:java概述:1,JDK:Java Development Kit,java的開發(fā)和運行環(huán)境,java的開發(fā)工...
    ZaneInTheSun閱讀 2,669評論 0 11
  • 早上六點起床,穿戴完畢,對著鏡子笑了一下,希望今天的生日過得快樂。 然后,看到婆婆送的大紅包。昨晚她明明比我先睡,...
    Sissi張弛閱讀 271評論 0 0