Scala中的动态继承
我有一个名为Scala中的动态继承,scala,inheritance,composition,Scala,Inheritance,Composition,我有一个名为grandparent的抽象祖父母类,一个名为ParentOne的父类,还有几个名为ChildOne,ChildTwo,ChildThree。。。等等 具体内容如下: abstract class Grandparent { val value: Int def print(): Unit = println(value) } class ParentOne extends Grandparent { override val value: Int = 1
grandparent
的抽象祖父母类,一个名为ParentOne
的父类,还有几个名为ChildOne
,ChildTwo
,ChildThree
。。。等等
具体内容如下:
abstract class Grandparent {
val value: Int
def print(): Unit = println(value)
}
class ParentOne extends Grandparent {
override val value: Int = 1
}
class ChildOne extends ParentOne
class ChildTwo extends ParentOne
class ChildThree extends ParentOne
我的目标是提供一种方法,将所有子类中打印的值
更改为例如2
。我希望这个方法尽可能简单
结果将类似于如下所示创建一个类ParentTwo
,并使所有子类继承它,而不是ParentOne
class ParentTwo extends Grandparent {
override val value: Int = 2
}
但是我知道这是不可能的,因为我们不能动态地改变超类。我想使图书馆的结构变得更好,以完成上述任务。最简单的方法是什么?如果你想要一个不变的解决方案,那么你必须引入一个成员。当前使用继承注入值。但这不能在运行时更改
一种解决方案是让子类携带以下值:
class ChildOne(value: Int) extends GrandParent
然后客户端必须在每个对象创建时指定值。您可以引入生成器,因此客户端只需指定一次:
case class ChildBuilder(value: Int) {
def buildChildOne = new ChildOne(value)
def buildChildTwo = new ChildTwo(value)
}
> builder = ChildBuilder(2)
> val child1 = builder.buildChildOne
> val child2 = builder.buildChildTwo
我不知道这是否是一个可行的解决方案。不知怎的,我觉得你应该一起改变你的方法。但是我不知道你想要实现什么。如果你想要一个不变的解决方案,那么你必须引入一个成员。当前使用继承注入值。但这不能在运行时更改
一种解决方案是让子类携带以下值:
class ChildOne(value: Int) extends GrandParent
然后客户端必须在每个对象创建时指定值。您可以引入生成器,因此客户端只需指定一次:
case class ChildBuilder(value: Int) {
def buildChildOne = new ChildOne(value)
def buildChildTwo = new ChildTwo(value)
}
> builder = ChildBuilder(2)
> val child1 = builder.buildChildOne
> val child2 = builder.buildChildTwo
我不知道这是否是一个可行的解决方案。不知怎的,我觉得你应该一起改变你的方法。但是我不知道你想要实现什么。你写的
我的目标是提供一种方法来改变
我将把它作为一个方法,它应该改变所有子类的值,对吗
如果是这样,您可以使用父类
的伴生对象来存储一个变量,该变量可以随意更改:
abstract class Grandparent {
def value: Int
def print(): Unit = println(value)
}
object Parent {
var mutableValue: Int = 1
}
class Parent extends Grandparent {
override def value: Int = Parent.mutableValue
}
class ChildOne extends Parent
class ChildTwo extends Parent
class ChildThree extends Parent
使用示例:
pablo-pablo@ val c = new ChildOne()
c: ChildOne = ammonite.$sess.cmd6$ChildOne@4ad10ef2
pablo-pablo@ c.value
res12: Int = 12
pablo-pablo@ Parent.mutableValue = 30
pablo-pablo@ c.value
res14: Int = 30
你写的
我的目标是提供一种方法来改变
我将把它作为一个方法,它应该改变所有子类的值,对吗
如果是这样,您可以使用父类
的伴生对象来存储一个变量,该变量可以随意更改:
abstract class Grandparent {
def value: Int
def print(): Unit = println(value)
}
object Parent {
var mutableValue: Int = 1
}
class Parent extends Grandparent {
override def value: Int = Parent.mutableValue
}
class ChildOne extends Parent
class ChildTwo extends Parent
class ChildThree extends Parent
使用示例:
pablo-pablo@ val c = new ChildOne()
c: ChildOne = ammonite.$sess.cmd6$ChildOne@4ad10ef2
pablo-pablo@ c.value
res12: Int = 12
pablo-pablo@ Parent.mutableValue = 30
pablo-pablo@ c.value
res14: Int = 30
使用隐式参数
需要value
方法通过隐式参数获取值。
客户端可以创建环境
,也可以提供可以导入的预制环境
请注意,实例将不拥有值
。必须在每次方法调用时提供它
case class Environment(value: Int)
trait Parent {
def value(implicit env: Environment): Int = env.value
}
class Child1 extends Parent
class Child2 extends Parent
//client code
implicit val env = Environment(2)
(new Child1).value == 2
(new Child2).value == 2
使用隐式参数
需要value
方法通过隐式参数获取值。
客户端可以创建环境
,也可以提供可以导入的预制环境
请注意,实例将不拥有值
。必须在每次方法调用时提供它
case class Environment(value: Int)
trait Parent {
def value(implicit env: Environment): Int = env.value
}
class Child1 extends Parent
class Child2 extends Parent
//client code
implicit val env = Environment(2)
(new Child1).value == 2
(new Child2).value == 2
混合溶液
混合溶液
谢谢你的反馈。我曾考虑过构建器类,但我有15个以上的类继承自祖辈类
类,人们甚至可以添加更多继承自该类的类。因此,生成器类可能不合适。我正在寻找一个灵活的解决方案,但似乎很难想到。也许我得重新考虑一下应用程序的结构。谢谢你的反馈。我曾考虑过构建器类,但我有15个以上的类继承自祖辈类
类,人们甚至可以添加更多继承自该类的类。因此,生成器类可能不合适。我正在寻找一个灵活的解决方案,但似乎很难想到。也许我必须重新考虑应用程序的结构。我想这是目前为止最好的解决方案。但是我不能否认它有一种使用全局变量的感觉。@SuhjinPark有点像,但不完全是这样,它更像是约束在类上下文中的静态变量。您可以将mutableValue
设为私有,并将方法changeValue
添加到Parent
对象中,这是更改它的唯一方法。你可以将这个方法包私有化……我想这是目前为止最好的解决方案。但是我不能否认它有一种使用全局变量的感觉。@SuhjinPark有点像,但不完全是这样,它更像是约束在类上下文中的静态变量。您可以将mutableValue
设为私有,并将方法changeValue
添加到Parent
对象中,这是更改它的唯一方法。您可以将该方法包设置为私有。。。