2014-04-28 89 views
1

在我的斯卡拉項目,我有下面的類層次結構:如何限制公共方法訪問超類?

class A { 

    def methodA = ... 
    ... other methods here ... 
} 

class B extends A { 

    ... other methods here ... 
} 

在我的一流的設計,它非常有意義,使BA一個子類。唯一的問題是methodA僅適用於A類,但不適用於B類。不幸的是,我不能將methodA設置爲私有,因爲它需要從類A的任何實例中調用。

我是否必須重新考慮我的班級設計還是可以將訪問公共方法methodA限制爲A班級?

+1

見http://en.wikipedia.org/wiki/Liskov_substitution_principle由此,A'的'任何情況下應該由'B',這是不能夠更換如果你不得不限制對'methodA'的訪問,那麼你應該重新考慮你的類設計。 – godfatherofpolka

+0

「唯一的問題是methodA只適用於A類」 - 那麼爲什麼要擴展B來包含它呢? – brumScouse

+0

@brumScouse類'A'還有其他一些對類'B'有用的方法,除了這個方法'methodA'外。這就是爲什麼我用類「A」擴展類「B」。 – pemistahl

回答

3

在我的一流的設計,它非常有意義使得B A的一個子類唯一的問題是,是了methodA僅適用於A類而不是B類

這些語句可以在同一時間不會是真的。

不幸的是,我無法設置了methodA私人,因爲它需要從A類的任何實例

B每個實例是A一個實例可以被調用(這正是「子」的意思)。因此,如果該方法不能從B的實例中調用,則它不是「可從類A的任何實例中調用的」。

+0

我雖然想得很多,但我並不完全確定。然後,我必須將這兩個類分開,並重復這兩個類中常用方法的代碼。我不喜歡它,但顯然沒有其他辦法。 – pemistahl

+1

@pemistahl您可能想看看http://en.wikipedia.org/wiki/Circle-ellipse_problem或考慮將共享代碼轉換爲共同特徵。 – godfatherofpolka

+1

@pemistahl不,你可以有一個超類(或特徵),其中包含所有實際的通用代碼。如果你真的想讓'methodA'存在'B'中,但不公開(因爲它在其他方法的實現中被調用),它可以在超類中被保護並被覆蓋以在'A'中被公開。否則,把它放在'A'中。 –

0

一個下列可能的方式:

class A protected() { 
    //.... methods .... 
} 

trait AExt extends A { 
    def foo(s : String) = println(s) 
} 

object A { 
    def apply() : A with AExt = new A with AExt 
} 

class B extends A { 
    //.... methods .... 
} 

val a = A() 
a.foo("hello") 

val b = new B() 
// b.foo("hello") // no 'foo' method