<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    隨筆 - 11  文章 - 33  trackbacks - 0
    <2007年9月>
    2627282930311
    2345678
    9101112131415
    16171819202122
    23242526272829
    30123456

    常用鏈接

    留言簿(1)

    隨筆分類

    隨筆檔案

    文章檔案

    搜索

    •  

    最新隨筆

    最新評論

    閱讀排行榜

    評論排行榜

    本文假定讀者已經了解有關正方形不是長方形的相關內容。
            
            之前人們討論的正方形長方形的問題的關鍵在哪里?我覺得就在于改動長方形的邊的長度。我們可以這么考慮一下,一個長方形的instance的邊長應該是可變的嗎?我覺得一旦一個長方形的邊長改變之后它就成了另一個長方形了(一個新的instance)。所以長方形類里面不應該有改變其邊長的方法,一個長方形實例各個的邊長應當在new它的時候確定下來,并且它們應當是immutable的。基于這種考慮,我設計的長方形和正方形的類如下所示:
    //長方形
    public class Rectangle {
      private final int width;
      private final int height;
     
      public Rectangle(int width, int height) {
        this.width = width;
        this.height = height;
      }
     
      public int getWidth() {
        return width;
      }

      public int getHeight() {
        return height;
      }
     
      public int getArea() {
        return width*height;
      }
    }

    //正方形
    public class Square extends Rectangle{
      private final int side;
     
      public Square(int side) {
        super(side, side);
        this.side = side;
      }
     
      public int getSide() {
        return side;
      }
    }

            這種繼承關系就既符合現實中的父子關系也遵循LSP。之所以這么設計,我的想法是一個類所具有的方法不應當能夠改變其本質。比如有一個Men類,它可以有eat(),sleep(),work(),makeLovewith(Person p)方法,但是如果你在里面定義denatureToWomen(),denatureToEunuch()就很不恰當了,因為這改變了其本質,導致這個Men的實例不再屬于Men類(至少已經和現實不吻合)了。除非這兩個方法不能改變該實例本質,否則在Men里面定義這兩個方法本身就是有問題的。不過如果用下面這種方式定義也許可行:
    public Women denatureToWomen() {
      Women w = new Women();
      //set attributes here
      return w;
    }

    public Eunuch denatureToEunuch() {
      Eunuch e = new Eunuch();
      //set attributes here
      return e;
    }

    這樣一來,調用denatureToWomen()會產生一個新的實例,原來的那個Men實例依然存在,這和現實生活依然不吻合,現實生活中一個實例不光可以上型(upcast),還可以平行型,寒。。。

    總之一句話,一個類的方法不應該改變其實例的本質。

    posted on 2007-09-20 16:33 teasp 閱讀(2728) 評論(13)  編輯  收藏 所屬分類: Java學習

    FeedBack:
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 16:43 千里冰封
    呵呵,有意思  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 18:29 GandofYan
    new Square (4,5);

    會有什么結果呢?  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 18:45 teasp
    @GandofYan
    兄弟啊,Square只有一個構造方法,你說的這句有語法錯誤哦。  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 19:55 GandofYan
    @teasp


    哦,sorry,我一直以為構造方法子類是繼承的
    我說錯了:)  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 20:38 黑蝙蝠
    makeLovewith你取的方法名字真酷 呵呵

    還是沒明白你到底想表達什么》??  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 21:33 teasp
    @黑蝙蝠

    呵呵,我不知道你有沒有看過關于正方形不是長方形的討論,網上有的,另外《Java與模式》里面第79頁左右就是講這個問題的。如果你看過相關的內容,應該能明白我要表達的意思了。  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-20 21:49 teasp
    沒看過相關討論的可以看看這個先:

    長方形有二個屬性長和寬。并有一個設置長的方法和設置寬的方法,還有一個求面積的方法.
    像下面
    private int length;
    private int width;
    public void setLength(int lenght) {
    this.length = lenght;
    }
    public void setWidth(int width) {
    this.width= width;
    }
    public int getArea() {
    return this.length * this.width;
    }
    如果說正方形是長方形的子類。為了保證正方形長和寬相等,那對應于正方形的二設置長寬的個方法就得改成
    public void setLength(int lenght) {
    this.length = lenght;
    this.width= lenght;
    }
    public void setWidth(int width) {
    this.length = width;
    this.width= width;
    }
    那我們想想用戶使用時候的情景。 我們都知道長方形的面積等于長與寬的積。那當我們用長方形的時候我們會這樣用
    Rectangle rectangle = new Rectangle();
    rectangle.setLength(5);
    rectangle.setWidth(4);
    我們想知道面積是多少我們就可以
    rectangle.getArea();
    得到的是20,當然結果是非常正確的。
    但想想如果我們把一個正方形的實例給用戶用的時候會怎么樣
    Rectangle rectangle = new Square(); //注意,這里體顯代換原則。用戶根本不知道真正的實例是正方形,用戶只知道長方形的事情。
    rectangle.setLength(5);
    rectangle.setWidth(4);
    我們想知道面積是多少我們就可以
    rectangle.getArea();
    得到的結果卻是 16 ,這違背了長方形的面積是長與寬之積的原則。用戶就不會明白為什么我設置了長是5寬是4得到的答案卻是16 ?? 與前提不符
    所以正方形不能代替長方形出現在這個地方。
    也就是說正方形不應當看作是長方形的子類。
      回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-21 10:27 辛科
    認同樓主  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-21 16:38 dominobaby
    繼承是泛化,是擴展,結果是:女人不是人,但翠花是人!
    作者的看法確實可取,邊長似乎確實是方形的標志性。
    但是這樣的話,哪些作為不可變量很難確定。比如:矮子是不是人?想一個矮子類,就得把高矮也定為不可變量,可是這就跟人的生長特性矛盾了。
      回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-21 17:51 teasp
    樓上說得很有道理,最關鍵的問題是我們不知道哪些特性才是一個類的標志。因為現實世界太復雜了,簡直不可模仿  回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-23 20:21 zenny_chen
    我認為將正方形作為長方形的子類本身是一個錯誤的概念。
    實際上我們應該將面向對象中的繼承與離散數學的集合論聯系起來:
    例如有集合A={a, b, c}, B={a, b}。這里顯然B是A的子集。然而如果用面向對象的方法將這兩個集合構造為兩個具有繼承關系的類結構的話很顯然,應該將集合B作為父類而將集合A作為B的子類。
    因此,像public class Square extends Rectangle這種寫法欠妥。作為正方形其元素就只要一個邊長,而矩形則要兩個。因此,根據上面的集合,可以列出Square={a}, Rectangle={a, b}。很顯然,應該將正方形作為父類,而矩形作為正方形的子類。(當然,作為集合元素應該為集合類型,而不是組合。不過在軟件設計建模上暫且就如此表示)。

    在做面向對象的設計時,不應該死板地去看待現有邏輯,盡管我們一直認為正方形是矩形的一個子類(特殊類)。但根據繼承的概念——子類繼承父類的所有屬性和操作這一概念,在很多時候集合中的子集關系與面向對象中的繼承關系是相反的。

      回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-23 20:26 zenny_chen
    對了。在這里說明一下,上面提到的“Square={a}, Rectangle={a, b}”中Square和Rectangle是指正方形與矩形的邊長集,而不是指正方形與矩形的集合。
      回復  更多評論
      
    # re: 正方形不是長方形的終極解決辦法 2007-09-24 10:45 真的遵循LSP?
    長方形在這里只是舉個例子 ,在一個類中改變一個類的屬性的方法是很正常的需求,既然原來的結論:
    "也就是說正方形不應當看作是長方形的子類。 "

    那正方形類就不應改繼承長方形類.  回復  更多評論
      
    主站蜘蛛池模板: 久久精品国产亚洲AV高清热| 免费国产美女爽到喷出水来视频| 亚洲一区无码精品色| 亚洲av日韩精品久久久久久a| 成人片黄网站A毛片免费| 日本亚洲免费无线码| 免费看美女裸露无档网站| 亚洲国产成+人+综合| 欧洲黑大粗无码免费| 亚洲av无码一区二区三区在线播放 | 国产亚洲精品成人AA片新蒲金| 国产精品亚洲综合天堂夜夜| 日本不卡视频免费| 无人视频免费观看免费视频| 亚洲XX00视频| 中国一级特黄高清免费的大片中国一级黄色片 | 亚洲精品高清国产麻豆专区| 91精品国产免费入口| 亚洲国产成人超福利久久精品| **一级毛片免费完整视| 亚洲一区二区无码偷拍| 免费h黄肉动漫在线观看| 国产V片在线播放免费无码 | 亚洲成无码人在线观看| 成人黄软件网18免费下载成人黄18免费视频 | 18禁止看的免费污网站| 亚洲三级高清免费| 曰皮全部过程视频免费国产30分钟| 亚洲heyzo专区无码综合| 亚洲精品一级无码鲁丝片| 国产拍拍拍无码视频免费| 亚洲一区二区影视| 四虎免费久久影院| 免费日本一区二区| 亚洲国产综合精品中文第一| xvideos亚洲永久网址| 久久久久久免费一区二区三区 | 亚洲国产精品第一区二区三区| 国产精成人品日日拍夜夜免费| 亚洲人配人种jizz| 91麻豆精品国产自产在线观看亚洲 |