Android基礎進階之EffectiveJava翻譯系列(第三章:類和接口)

3. 類和接口

類和接口是Java編程的核心

Item13 最小化類和成員變量的訪問權限

信息隱藏與封裝是程序設計的基本原則
通用經(jīng)驗是能讓類或者變量不可訪問就讓它不可訪問
四種訪問權限:

  • private
    只在它聲明的地方可用
  • package-private
    同一個包內可用
  • protected
    同一個包或子類可用
  • public
    任何地方可用

公共類不應包含公共字段。確保static final引用的對象是不可變的每窖。
絕不可以用private static final來聲明一個數(shù)組對象

Item14 用公共方法提供公共字段
//bad
public class Point {
  public int x;
  public int y;
}

//good
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 double getY() { return y; }
    public void setX(double x) { this.x = x; }
    public void setY(double y) { this.y = y; }
}
Item15 最小化可變性

對象始終不變的類比可變的更安全和好用,如String
我們設計不可變對象時應遵循如下準則:

  • 不要提供任何方法來改變對象的狀態(tài)
  • 確保類不可繼承
  • 所有的字段使用private final修飾
  • 確保不要讓類中的可變對象訪問,使用深拷貝替代
    如果一個類確實可變,也要保證其它地方盡可能不變,TimerTask是很好的例子
Item16 組合和繼承,優(yōu)先使用組合

繼承雖然有很多好處,但是違背了封裝性,暴露了父類的實現(xiàn)細節(jié)

Item17 專用于繼承的設計趁仙,否則禁止繼承

未能理解,后續(xù)補充

Item18 接口和抽象類之間傾向于接口

Java提供了兩種機制來提供多個類型定義的實現(xiàn):接口和抽象類

最明顯的區(qū)別在于抽象類允許某些方法的實現(xiàn),更重要的區(qū)別在于一個類使用了抽象類的方式來定義,則這個類必須是抽象類的子類.因為Java只允許單一繼承亲澡,因此對抽象類的這種限制嚴重影響了它們作為類型定義的使用

  • 已經(jīng)存在的類可以很容易的實現(xiàn)一個新的接口
    比如實現(xiàn)Comparable接口
  • 接口是定義混合器的理想選擇
    比如為一個主要類型的類添加比較方法,可通過實現(xiàn)Comparable接口實現(xiàn)實例之間的排序

有一個特例是抽象類比接口更加易用,如果注重程序的易用性而不是靈活性則可以考慮抽象類

Item19 僅使用接口定義類型

當一個類實現(xiàn)了一個接口,這個接口是為類的實例服務的而不是為了其他目的

所以有一種常量接口盡量不要使用

//bad
public interface PhysicalConstants {
    // Avogadro's number (1/mol)
    static final double AVOGADROS_NUMBER = 6.02214199e23;
    // Boltzmann constant (J/K)
    static final double BOLTZMANN_CONSTANT = 1.3806503e-23;
    // Mass of the electron (kg)
    static final double ELECTRON_MASS = 9.10938188e-31;
}

如果有這種常量需要使用,可以把它定義在與之關聯(lián)的類里面

Item20 用繼承來替代復合類(原單詞: tagged classes)

偶爾會遇到一個類的實例包含了多種不同的類別,如下

// bad Tagged class - vastly inferior to a class hierarchy!
class Figure {
    enum Shape { RECTANGLE, CIRCLE };
    // Tag field - the shape of this figure
    final Shape shape;
    // These fields are used only if shape is RECTANGLE
    double length;
    double width;
    // This field is used only if shape is CIRCLE
    double radius;
    // Constructor for circle
    Figure(double radius) {
        shape = Shape.CIRCLE;
        this.radius = radius;
    }
    // Constructor for rectangle
    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();
        }
    }
}  

優(yōu)化如下

//Class hierarchy replacement for a tagged class
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; }
} 
Item21 使用函數(shù)對象表示策略

直譯過來有點不好理解,大意是對于多個類都要使用的策略(或用方法表示),采用接口來實現(xiàn)

如一個類需要比較方法,另一個類也需要,則抽象出一個Comparable接口來給各個類通用

Item22 嵌套類的使用

有四種嵌套類,分別是靜態(tài)成員類灶搜、非靜態(tài)成員類、匿名內部類和本地類
除了第一個都是內部類

  • 靜態(tài)成員類
    可以訪問外部類的私有屬性
  • 非靜態(tài)成員類
    同靜態(tài)成員類,區(qū)別在于沒有static修飾
public class MySet<E> extends AbstractSet<E> {
    public Iterator<E> iterator() {
        return new MyIterator();
    }
    //典型用法
    private class MyIterator implements Iterator<E> {
    ...
    }
}
  • 匿名內部類
    不用聲明,常用于監(jiān)聽器,隨用隨銷
  • 本地類
    略 未能理解,后續(xù)補充,歡迎留言增益知識

如果成員類需要外部類的引用,則使用非靜態(tài)成員類,否則使用靜態(tài)成員類


上一章:Object的方法
下一章:泛型

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末帮非,一起剝皮案震驚了整個濱河市怔檩,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌空猜,老刑警劉巖绽慈,帶你破解...
    沈念sama閱讀 222,464評論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件诺核,死亡現(xiàn)場離奇詭異,居然都是意外死亡久信,警方通過查閱死者的電腦和手機窖杀,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來裙士,“玉大人入客,你說我怎么就攤上這事⊥茸担” “怎么了桌硫?”我有些...
    開封第一講書人閱讀 169,078評論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長啃炸。 經(jīng)常有香客問我铆隘,道長,這世上最難降的妖魔是什么南用? 我笑而不...
    開封第一講書人閱讀 59,979評論 1 299
  • 正文 為了忘掉前任膀钠,我火速辦了婚禮,結果婚禮上裹虫,老公的妹妹穿的比我還像新娘肿嘲。我一直安慰自己,他們只是感情好筑公,可當我...
    茶點故事閱讀 69,001評論 6 398
  • 文/花漫 我一把揭開白布雳窟。 她就那樣靜靜地躺著,像睡著了一般匣屡。 火紅的嫁衣襯著肌膚如雪封救。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,584評論 1 312
  • 那天捣作,我揣著相機與錄音誉结,去河邊找鬼。 笑死虾宇,一個胖子當著我的面吹牛搓彻,可吹牛的內容都是我干的。 我是一名探鬼主播嘱朽,決...
    沈念sama閱讀 41,085評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼旭贬,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了搪泳?” 一聲冷哼從身側響起稀轨,我...
    開封第一講書人閱讀 40,023評論 0 277
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎岸军,沒想到半個月后奋刽,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體瓦侮,經(jīng)...
    沈念sama閱讀 46,555評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,626評論 3 342
  • 正文 我和宋清朗相戀三年佣谐,在試婚紗的時候發(fā)現(xiàn)自己被綠了肚吏。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,769評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡狭魂,死狀恐怖罚攀,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情雌澄,我是刑警寧澤斋泄,帶...
    沈念sama閱讀 36,439評論 5 351
  • 正文 年R本政府宣布,位于F島的核電站镐牺,受9級特大地震影響炫掐,放射性物質發(fā)生泄漏。R本人自食惡果不足惜睬涧,卻給世界環(huán)境...
    茶點故事閱讀 42,115評論 3 335
  • 文/蒙蒙 一募胃、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧宙地,春花似錦摔认、人聲如沸逆皮。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽电谣。三九已至秽梅,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間剿牺,已是汗流浹背企垦。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評論 1 274
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晒来,地道東北人钞诡。 一個月前我還...
    沈念sama閱讀 49,191評論 3 378
  • 正文 我出身青樓,卻偏偏與公主長得像湃崩,于是被迫代替她去往敵國和親荧降。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 45,781評論 2 361