【问题标题】:Abstract class to provide methods specific to extending class/object提供特定于扩展类/对象的方法的抽象类
【发布时间】:2015-03-10 03:22:54
【问题描述】:

我有一大堆模型要清理。所以基本上,模型看起来像;

case class ExampleModel(…) extends Model {
    …
}

object ExampleModel {
    def find = new Finder[Long, ExampleModel](classOf[Long], classOf[ExampleModel]) // very repetitive
    …
}

现在,我一直在尝试定义一个 abstract class,它为我提供了一个伴随对象特定的 find 方法;

abstract class Findable[T: ClassTag] {
  self: T => def find = new Finder[Long, T](classOf[Long], classOf[T])
}

但编译失败:

class type required but T found

解决这个问题的正确方法是什么?

【问题讨论】:

    标签: scala inheritance abstract-class


    【解决方案1】:

    你不能使用 T 作为自我类型,因为它在类定义的那一刻是未知的(就像你不能写class A[T] extends T一样),当你有 ClassTag 时你也不需要传递 classOf,所以应该足够了:

    scala> class Finder[A: ClassTag, B: ClassTag](){def getA = classTag[A].runtimeClass}
    defined class Finder
    
    scala> abstract class Findable[T: ClassTag] {def find = new Finder[Long, T]}
    defined class Findable
    

    最后:

    scala> :paste
    // Entering paste mode (ctrl-D to finish)
    
    case class ExampleModel()
    object ExampleModel extends Findable[ExampleModel]
    
    
    // Exiting paste mode, now interpreting.
    
    defined class ExampleModel
    defined object ExampleModel
    

    注意这里的 T 是case class ExampleModel,但你可以simply obtain the companion

    【讨论】:

    • 如果我不想定义自己的Finder怎么办?
    • 然后按原样使用它 - def find = new Finder[Long, T](classOf[Long], classTag[T].runtimeClass)
    • 如果您需要伴随对象而不是案例类 - 您可以使用 JavaReflection 的 Class.forName 获取它,这里的命名约定 - stackoverflow.com/questions/27629215/…
    【解决方案2】:

    为什么不直接

    class Findable[T](clazz: Class[T]) {
         def find(clazz: Class[T]) = new Finder(classOf[Long], clazz)
    }
    
    object ExampleModel extends Findable(classOf[ExampleModel]) 
    

    【讨论】:

    • 哦,来吧。 “问题”是修辞性的。 “为什么不这样做?”只是说“这样做”的一种礼貌形式。现在是语言学论坛吗?这是正确的方法,因为它可以编译和工作,这就是 OP 所要求的。 cmets 不是正确的方法。将鼠标悬停在“添加评论”上,看看为什么。
    • @Dima - 如果你记得我在评论你的另一个答案时也提到了同样的事情。当你给出答案时,尽量不要把它当作一个问题来表达,并解释它,而不是仅仅写代码。这将使您的答案更符合 SO 的要求,并且您将避免将它们发送到最后投票。
    • @Dima - 我这样说并不是为了冒犯你个人。您的答案屡屡获得接近投票,这只是一个事实。我说它是为了帮助你找出原因。不必一次与每个特定的投票者争论,而只需尝试了解它发生的原因。
    • @Dima - 好吧,我真的不想在这里争论。我看到你的名字又出现了,我真的很想帮助你弄清楚为什么你会获得接近的选票。在 SO 中,问题/答案的格式也很重要,而不仅仅是内容。就像在由社区编辑的维基百科中一样,并非一切都顺利,因为有一些标准。祝你好运,与每个投票分别删除你的答案的人争论。我试着帮忙,就是这样。即使你说服了我,你还有成千上万的人需要说服。
    • @Dima - 是的,它是关于有用性的,这个答案对于任何目的都没有真正有用,而不是解决这个确切的问题,没有解释或可能从中学习,因此它可能对其他人毫无价值可能会通过使用谷歌来解决这个问题的人也试图解决这个问题。因此,downvote 中包含的 downvote 和自动评论。诚然,这不仅仅与形式有关,但某种解释永远不会受到伤害;)
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-06-28
    • 1970-01-01
    • 2012-08-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多