代码之家  ›  专栏  ›  技术社区  ›  sid802

在scala泛型类中实现字段

  •  0
  • sid802  · 技术社区  · 7 年前

    我需要一些关于scala的通用特性的帮助。

    我有一个类,它的方法返回类型t。 在我的类的每一个实现中,我想返回一个可以使用的子类T。

    基本上,在我的抽象类中,我需要一个返回一个对象的方法,每一个实现都有它自己的实现。 此外,我希望将抽象类与另一个抽象类子类化,更进一步地限制这一对象(一个原始对象的子类)。不管我做什么,我都会遇到编译错误。

    这就是我尝试过的:

    case class MyConfigs()
    
    trait WithMyConfigs {
      def myConfigs: MyConfigs
    }
    
    case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs
    
    case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs
    
    
        trait AbstractClass {
          def configs[B <: WithMyConfigs]: B
        }
    
        class ImplLimitClass extends AbstractClass {
          override def configs[B <: WithMyConfigs]: B = LimitConfigs(MyConfigs(), 5)
        }
    
        class ImplSizeClass extends AbstractClass {
          override def configs[B <: WithMyConfigs]: B = TextConfigs(MyConfigs(), "test")
        }
    
        trait WithRestrictedConfigs extends WithMyConfigs {
          def additionalIntField: Int
        }
    
        trait RestrictedAbstractClass extends AbstractClass {
          override def configs[B <: WithRestrictedConfigs]: B
        }
    
        case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs
    
        class ImplRestrictedClass extends RestrictedAbstractClass {
          override def configs[B <: WithRestrictedConfigs]: B = RestrictedConfigs(MyConfigs(), 5)
        }
    

    这样我就得到了“textconfigs/limitconfigs类型的错误表达式不符合预期的类型b”。

    我也试过以下方法:

    case class MyConfigs()
    
    trait WithMyConfigs {
      def myConfigs: MyConfigs
    }
    
    case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs
    
    case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs
    
    
    trait AbstractClass {
    
      type B <: WithMyConfigs
    
      def configs: B
    }
    
    class ImplLimitClass extends AbstractClass {
      override def configs: B = LimitConfigs(MyConfigs(), 5)
    }
    
    class ImplSizeClass extends AbstractClass {
      override def configs: B = TextConfigs(MyConfigs(), "test")
    }
    
    trait WithRestrictedConfigs extends WithMyConfigs {
      def additionalIntField: Int
    }
    
    trait RestrictedAbstractClass extends AbstractClass {
      override type B <: WithRestrictedConfigs
      override def configs: B
    }
    
    case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs
    
    class ImplRestrictedClass extends RestrictedAbstractClass {
      override def configs: B = RestrictedConfigs(MyConfigs(), 5)
    }
    

    然后我得到“xxx类型的表达式不符合预期的impleStritedClass.this.b类型”。

    如果有人知道如何帮助,那就太好了:)

    1 回复  |  直到 7 年前
        1
  •  1
  •   rad i    7 年前

    您需要在实现中定义实际类型。看看 scala-doc 是的。

    下面是一个编译示例:

    case class MyConfigs()
    
    trait WithMyConfigs {
      def myConfigs: MyConfigs
    }
    
    case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs
    
    case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs
    
    
    trait AbstractClass {
      type T <: WithMyConfigs
      def configs :T
    }
    
    class ImplLimitClass extends AbstractClass {
      type T = LimitConfigs
      override def configs: T = LimitConfigs(MyConfigs(), 5)
    }
    
    class ImplSizeClass extends AbstractClass {
      type T = TextConfigs
      override def configs: T = TextConfigs(MyConfigs(), "test")
    }
    
    trait WithRestrictedConfigs extends WithMyConfigs {
      def additionalIntField: Int
    }
    
    trait RestrictedAbstractClass extends AbstractClass {
      type T <: WithRestrictedConfigs
      override def configs: T
    }
    
    case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs
    
    class ImplRestrictedClass extends RestrictedAbstractClass {
      type T = RestrictedConfigs
      override def configs: T = RestrictedConfigs(MyConfigs(), 5)
    }
    

    [更新]

    你需要在某个地方指定你的类型。如果使用类型参数,您将得到如下信息:

    trait AbstractClass[T <: WithMyConfigs] {
      def configs: T
    }
    
    class ImplLimitClass extends AbstractClass[LimitConfigs] {
      override def configs = LimitConfigs(MyConfigs(), 5)
    }
    
    class ImplSizeClass extends AbstractClass[WithMyConfigs] {
      override def configs = TextConfigs(MyConfigs(), "test")
    }
    

    当然,您可以指定特性本身来获得更一般的配置(参见 ImplSizeClass 以上) 然后用一个额外的特征隐藏类型参数。

    trait SpecAbstractClass extends AbstractClass[WithMyConfigs]
    

    如果您不想指定显式类型,为什么不使用老式的接口方式:

    case class MyConfigs()
    
    trait WithMyConfigs {
      def myConfigs: MyConfigs
    }
    
    case class LimitConfigs(myConfigs: MyConfigs, limit: Int) extends WithMyConfigs
    
    case class TextConfigs(myConfigs: MyConfigs, text: String) extends WithMyConfigs
    
    
    trait AbstractClass {
      def configs: WithMyConfigs
    }
    
    class ImplLimitClass extends AbstractClass {
      override def configs = LimitConfigs(MyConfigs(), 5)
    }
    
    class ImplSizeClass extends AbstractClass {
      override def configs = TextConfigs(MyConfigs(), "test")
    }
    
    trait WithRestrictedConfigs extends WithMyConfigs {
      def additionalIntField: Int
    }
    
    trait RestrictedAbstractClass extends AbstractClass {
      override def configs: WithRestrictedConfigs
    }
    
    case class RestrictedConfigs(myConfigs: MyConfigs, additionalIntField: Int) extends WithRestrictedConfigs
    
    class ImplRestrictedClass extends RestrictedAbstractClass {
      override def configs = RestrictedConfigs(MyConfigs(), 5)
    }