Rah*_*hul 101 oop scala companion-object
是否需要一个类的伴随对象(单例)?为什么我要创建一个类,比如说Foo并为它创建一个伴随对象?
Sae*_*aem 75
伴侣对象基本上提供了一个可以放置"静态"方法的地方.此外,伴随对象或伴随模块可以完全访问类成员,包括私有成员.
Companion对象非常适合封装工厂方法之类的东西.而不必有,例如,Foo和FooFactory无处不在,你可以有一个伴侣对象的类采取在工厂的责任.
Cra*_*lin 60
伴随对象对于存储类的所有实例共有的状态和方法很有用,但它们不使用静态方法或字段.它们使用常规虚拟方法,可以通过继承覆盖它们.Scala真的没有任何静态.有很多方法可以使用它,但这是一个简单的例子.
abstract class AnimalCounter
{
var animals = 0
def name: String
def count()
{
animals += 1
println("%d %ss created so far".format(animals, name))
}
}
abstract class Animal
{
def companion: AnimalCounter
companion.count()
}
object Dog extends AnimalCounter
{
val name = "dog"
}
class Dog extends Animal
{
def companion = Dog
}
object Cat extends AnimalCounter
{
val name = "cat"
}
class Cat extends Animal
{
def companion = Cat
}
Run Code Online (Sandbox Code Playgroud)
哪个产生这个输出:
scala> new Dog
1 dogs created so far
scala> new Cat
1 cats created so far
scala> new Dog
2 dogs created so far
scala> new Cat
2 cats created so far
Run Code Online (Sandbox Code Playgroud)
Szy*_*him 30
...它是为伴随类存储静态工厂方法(而不是DP)的好地方.如果您命名那些重载的工厂方法apply(/ ... /),您将能够创建/初始化您的类
没有'新'(不是那么重要)
使用不同的可能参数集(与Bloch在Effective Java中关于telescoping构造函数的内容相比)
能够决定你想要创建哪个派生类而不是抽象(伴随)派生类
示例代码:
abstract class AbstractClass;
class RealThing(s: String) extends AbstractClass;
class AlternativeThing(i: Int) extends AbstractClass;
object AbstractClass {
def apply(s: String) = {
new RealThing(s)
}
def apply(i: Int) = {
new AlternativeThing(i)
}
}
// somewhere else you can
val vs = AbstractClass("asdf") // gives you the RealThing wrapped over string
val vi = AbstractClass(123) // gives you AlternativeThing wrapped over int
Run Code Online (Sandbox Code Playgroud)
我不会调用对象/基类AbstractXxxxx,因为它看起来并不坏:就像创建一些抽象的东西.给这些名字一个真正的意义.考虑使用不可变的,方法较少的case类并密封抽象基类.