为什么Kotlin / Scala伴随对象可以实现某些接口,这有什么好处?何时使用此功能很有用?
答案 0 :(得分:3)
因为companion object
是object
s,object
可以实现接口(或扩展类),并且没有充分的理由不允许它companion object
特别
Scala的一个常见用途是工厂:例如Seq
,List
,Vector
等协作对象都扩展TraversableFactory
,因此您可以编写使用TraversableFactory
的代码并传递其中任何一个来构造类型你要。 E.g。
def build[CC[X] <: Traversable[X] with GenericTraversableTemplate[X, CC], A](factory: TraversableFactory[CC])(elems: A*) = factory(elems)
// build(List)(1,2,3) == List(1, 2, 3)
// build(Set)(1,2,3) == Set(1, 2, 3)
类似地,所有案例类伴随对象都扩展了函数类型。
答案 1 :(得分:1)
当您在程序中只需要一个特定类的实例时,可以使用单例对象。
E.g。 Scala的Nil
实现Nil
。而不是每种类型的列表都可以实现它的特定 implicit object
,而只有其中一种。
在typeclass pattern中,您只有一个public static Something
用于相应的实施。
此外,如果您在Java中创建object Blah extends Renderable
,则可以在随播广告对象中创建该广告。
我个人认为它们对于实现sbt插件很有用,它会将blah.html
呈现给文件 customViewHolder.increase.setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
Double rate=Double.parseDouble(customViewHolder.total.getText().toString());
Log.e("rate",rate+"");
Double newrate=rate-((Double.parseDouble(feedItem.getRate())-Double.parseDouble(feedItem.getDiscount()))*(minteger-1));
Log.e("minusval",""+((Double.parseDouble(feedItem.getRate())-Double.parseDouble(feedItem.getDiscount()))*(minteger-1)));
Double ratetext=newrate+(Double.parseDouble(feedItem.getRate())-Double.parseDouble(feedItem.getDiscount()))*minteger;
Log.e("ratetext",ratetext+"");
Double discrate=Double.parseDouble(customViewHolder.disctotal.getText().toString());
Double newdiscrate=discrate-(Double.parseDouble(feedItem.getDiscount())*(minteger-1));
Double disctext=newdiscrate+Double.parseDouble(feedItem.getDiscount())*minteger;
Log.e("ratettttttttext",ratetext+"");
customViewHolder.total.setText(""+ratetext);// not working
ustomViewHolder.totalnew.setText(ratetext+"");// not working
customViewHolder.disctotal.setText(disctext+"");// not working
}
});
。详细了解有用性here。我必须知道它实现了这个特性!
答案 2 :(得分:1)
您可以将companion object
和继承用于某种级别的类级别或静态多态性。
考虑一个界面
interface Factory<T> {
fun create(): T
}
现在,我们创建一个其伴侣对象实现它的类
class Foo {
companion object: Factory<Foo> {
override fun create() = Foo()
}
}
现在我们可以为所有工厂创建一个扩展功能,例如记录对象。
fun <T> Factory<T>.createAndLog(): T {
val t = create()
println(t)
return t
}
不要像这样使用
Foo.createAndLog()
考虑标记界面
interface Queryable<T>
我们现在有两个类User
和Article
,它们代表companion object
实现接口的数据库中的表。
class User(val id: String) {
companion object: Queryable<User> {}
}
class Article(val authorId: String) {
companion object: : Queryable<Article> {}
}
我们现在可以定义一个扩展函数来从类
创建查询fun <T> Queryable<T>.query() = db.createQuery<T>()
我们可以称之为
User.query()
//or
Article.query()