2017-03-17 42 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变量'。 –