2017-01-20 63 views
-2

我有兩個類:Fullfill里氏替換原則

public class Base { 
    private final int value; 
    public Base(int value){ 
     this.value = value; 
    } 
    public int getValue(){ 
     return value; 
    } 
    public Base divide(Base that){ 
     return new Base(getValue()/that.getValue()); 
    } 
} 

public class Extended extends Base{ 
    public Extended(int value){ 
     super(value); 
    } 
    @Override public Extended divide(Base that){ 
     return new Extended(getValue()/that.getValue()); 
    } 
    public Extended getMax(Extended that){ 
     return new Extended(Math.max(getValue(), that.getValue())); 
    } 
} 

Base b = new Base(3); 
Extended c = new Extended(4); 

我的目標是fullfill Liskov替換原則,但雙方類不fullfill這個原則呢。我認爲他們不會因爲這不起作用:

Extended d = c.getMax(b); //doesn't work 
Extended e = c.getMax(c); 

既能類fullfill的原則,如果我想的getMax參數更改爲「基地那?

+1

什麼是'b'?什麼是'c'? – Andremoniy

+0

對不起,我忘了那些。 – binaryBigInt

回答

2

Liskov替代原則指出,擴展類型時,其要求應與基礎相同或更寬鬆,而其承諾應相同或更嚴格。類型的方法是我們感興趣在這裏檢查的主要內容。

我們不關心基類中不存在的方法,除非它們破壞了類的現有承諾,例如在沒有的情況下引入可變性。這種方法不會做那樣的事情,所以它是無關的:

public Extended getMax(Extended that){ 
    return new Extended(Math.max(getValue(), that.getValue())); 
} 

我們真的關心你重寫的方法。那麼,讓我們來看看你有一個:

public Base divide(Base that) { 
    return new Base(getValue()/that.getValue()); 
} 

@Override 
public Extended divide(Base that) { 
    return new Extended(getValue()/that.getValue()); 
} 
  • 基方法的要求是一個有效的Base實例傳遞和其getValue()不返回0。
  • 覆蓋方法的要求是有效的Base實例通過並且其getValue()不返回0.
  • 基本方法的承諾是返回有效的Base實例。
  • 覆蓋方法的承諾是返回有效的Base實例,該實例恰好是Extended實例。

因此,您正在向這些類別兌現Liskov替代原則。

您的片段不能編譯的原因無關與LSP:

Base b = new Base(3); 
Extended c = new Extended(4); 
Extended d = c.getMax(b); //doesn't work 
Extended e = c.getMax(c); 

只有一個getMax方法,它特別需要一個Extended實例。但是,您正在向其傳遞一個Base實例。

+0

這有什麼關係,這不起作用? '擴展d = b.divide(c);'(我在我的第一篇文章中添加了b和c) – binaryBigInt

+0

@binaryBigInt我已編輯包含它。 –