2017-03-17 78 views
1

我有一個抽象基類,用Scala編寫,擴展第三方(開源)的Java 7類:傳遞領域斯卡拉子類構造有Java的父母沒有類似的構造器

// The 3rd party Java 7 class 
public class Fizz { 
    private Foo foo; 
    private Buzz buzz; 

    public Fizz() { 
     // ... 
    } 

    public Fizz(Buzz buzz) { 
     // ... 
    } 

    // Getters and setters for foo + buzz down here 
} 

// My Scala classes 
abstract class Bar(val foo : Foo) extends Fizz { 
    // So I want my Bar API to accept a Foo, create an instance of Fizz via 
    // its no-arg ctor, and then call setFoo(...) with the foo accepted here. 
} 

class SkyBar extends Bar { 
    // ... 
} 

class SpaceBar extends Bar { 
    // ... 
} 

所以基本上我希望能夠構造新的SkyBarSpaceBar實例並且強制他們在其構造函數中接受Foo參數。隨後我想Bar構造函數:

  1. 調用它super()(無參數)父類的構造上Fizz;但隨後
  2. 撥打其父在Foo例如,通過其子類構造

我是新來的Scala和無法看透這裏樹木,不見森林傳遞setFoo(foo)二傳手。我如何讓所有這些一起來?!

回答

2

您只需在Bar的正文中撥打setFoo即可。

abstract class Bar(val foo: Foo) extends Fizz { 
    setFoo(foo) 
} 

我不認爲你想foo是公共領域,雖然(它是因爲val改性劑):

abstract class Bar(foo: Foo) extends Fizz { 
    setFoo(foo) 
} 

否則,你有一個不變的場foo和可變(獲取/設置)Foo屬性。

爲了詳細說明這一點,如果你讓一個fooval會碰到資料不一致的是這樣的:

scala> class Bar(val foo: Foo) extends Fizz { 
    | setFoo(foo) 
    | } 
defined class Bar 

scala> val bar = new Bar(Foo(1)) 
bar: Bar = [email protected] 

scala> bar.getFoo 
res7: Foo = Foo(1) 

scala> bar.foo 
res8: Foo = Foo(1) 

scala> bar.setFoo(Foo(2)) 

scala> bar.getFoo 
res10: Foo = Foo(2) 

scala> bar.foo 
res11: Foo = Foo(1) // still the old foo!!! 

如果你不讓它公開val沒有bar.foo

+0

謝謝@ Jasper-M(+1)但是我還沒有完全遵循100%。我明白你對'setFoo(foo)'的看法,這是完全合理的!但是,然後你就失去了我的領域與屬性之間的差異以及他們的可變性。因此,如果我使用第一個示例('val foo:Foo'),那麼'foo'會是「字段」還是「屬性」?它會是公共還是私人?它會變得可變還是不可變?再次感謝! – smeeb

+0

構造函數中的@smeeb'val foo'表示您有一個公共訪問的'val'或不可變的field/property/instance變量'foo'。沒有'val',它只是構造函數的本地參數。除非你從你的課堂的實例方法中引用它;那麼它就變成了這個類的私有實例變量,但這對程序員來說是完全透明的。 –

+0

字段與屬性等術語有點混淆,我只是用它們區分Scala'val'和Java'getter + setter + private變量'。 –