我是scala的新手,因此我的问题可能是由于对abtract类型和特征缺乏了解。
我目前有一个通用的传感器特性,它定义了一个值和newValue方法。
trait Sensor[T] {
def value: T
def newValue(): Unit = {}
}
Sensor的一个具体实现是MemorySensor,它只使用一个变量来存储值,并有一个设置值方法来设置值并触发newValue方法。
class MemorySensor[T] extends Sensor[T] {
var internalValue: T = null.asInstanceOf[T]
def setValue(newVal: T): Unit = {
internalValue = newVal
newValue()
}
def value: T = internalValue
}
还有一个AbstractSO(SO = subject + Observer)类,它使用抽象类型来实现Subject / Observer对。
class AbstractSO {
type O <: AbstractObserver
type S <: AbstractSubject
trait AbstractSubject {
this: S =>
def register(observer: O) = {
//we could use mutable collection here too
observers = observer :: observers
}
var observers: List[O] = List[O]()
def notifyObservers() = {
observers.foreach(o => o.notifyObserver(this))
}
}
trait AbstractObserver {
def notifyObserver(subject: S)
}
}
具体主题/观察者的一个例子是ActionSO
object ActionSO extends AbstractSO {
type S = ActionSubject
type O = ActionObserver
trait ActionSubject extends AbstractSubject {
def action() = {
notifyObservers()
}
}
trait ActionObserver extends AbstractObserver {
override def notifyObserver(actionSubject: ActionSubject) = {
println("action observer called")
}
}
}
现在我想为传感器实现一个具体的主题/观察者对,要求SensorSubject应该是传感器的混合特性。
所以我想目标就是像这样使用SensorSubject:
val x = new MemorySensor[Int] with SensorSubject[Int]
然而无论我尝试实现SensorSO,我总是得到某种“非法继承”错误或“自我类型不符合......”。
据我所知,如果不创建从AbstractSO扩展的额外类,但使用泛型类型,则无法完成此操作。 (但我不知道这有助于我实现目标)
如果有人可以帮助我,那将是非常好的!
修改
由于SergGr希望看到我的SensorSubject(这是我不知道如何实现的,我将发布我的各种尝试之一)
但请注意,这是 NOT COMPILE
object SensorSO extends AbstractSensorSO {
//TODO: i shouldn´t use "Any" here - this won´t work
override type S = SensorSubject[Any]
trait SensorSubject[T] extends AbstractSensorSubject with Sensor[T] {
this: S => //this generates problems as well
}
}
这是我的AbstractSensorSO
class AbstractSensorSO extends AbstractSO {
type S <: AbstractSensorSubject
type O <: AbstractSensorObserver
trait AbstractSensorSubject extends AbstractSubject {
this: S =>
}
trait AbstractSensorObserver extends AbstractObserver {
}
}
正如您所看到的,AbstractSensorSO基本上没有做任何事情,我只是添加了它,因为在创建具体的SensorSO对象之前,在解决方案的提示中提到了需要AbstractSO的子类。
我面临的一个问题是Sensor trait是通用的,因此SensorSubject使用Sensor trait AFAIK我必须使SensorSubject也是通用的。 通常情况下这不是问题,但是当我使用抽象类型时,我必须使用泛型来定义SensorSO中的“S”类型(例如
type S = SensorSubject[T]
但由于泛型类型“T”在该上下文中未知,因此显然会出错(因为通用“T”仅可用于通用特征SensorSubject的上下文) 如果我在定义类型S时尝试删除通用参数,我也会收到一条错误消息,指出缺少泛型类型参数。 只是写作
type S = SensorSubject[Any]
无法解决问题
EDIT2:
澄清我的目标是什么:
SensorSubject应该是一个Mixin Trait,这样我就可以使用普通传感器(不仅仅是MemorySensors),如果我想要的话,我可以添加“使用SensorSubject [Int]”来创建Sensor,然后它就像SensorSubject一样
这意味着我可以注册观察者,当我更改传感器的值(现在用作SensorSubject)时会通知观察者
以下是我想如何使用SensorSubject [T] Trait:
的示例//creating a sensor WITH the SensorSubject Trait
val sensorWithSubject= new MemorySensor[Int] with SensorSubject[Int]
sensorWithSubject.registerObserver(..)
//creating a normal Sensor WITHOUT SensorSubject
val normalMemSensor = new MemorySensor[Int]
答案 0 :(得分:1)
您没有提供预期用法的任何示例,因此我的猜测可能是错误的。我的尝试还在这里:
trait Sensor[T] {
def value: T
def newValue(): Unit = {}
}
class MemorySensor[T] extends Sensor[T] {
var internalValue: T = null.asInstanceOf[T]
def setValue(newVal: T): Unit = {
internalValue = newVal
newValue()
}
def value: T = internalValue
}
//////////////////////////////////
trait AbstractSubject[S <: AbstractSubject[S, O], O <: AbstractObserver[S, O]] {
this: S =>
def register(observer: O) = {
//we could use mutable collection here too
observers = observer :: observers
}
private var observers: List[O] = List[O]()
def notifyObservers() = {
observers.foreach(o => o.notifyObserver(this))
}
}
trait AbstractObserver[S <: AbstractSubject[S, O], O <: AbstractObserver[S, O]] {
def notifyObserver(subject: S)
}
//////////////////////////////////
trait SensorSubject[T, S <: SensorSubject[T, S, O], O <: SensorObserver[T, S, O]] extends Sensor[T] with AbstractSubject[S, O] {
this: S =>
}
trait SensorObserver[T, S <: SensorSubject[T, S, O], O <: SensorObserver[T, S, O]] extends AbstractObserver[S, O]
//////////////////////////////////
class MemorySensorSubject[T] extends MemorySensor[T] with AbstractSubject[MemorySensorSubject[T], MemorySensorObserver[T]] {
override def setValue(newVal: T): Unit = {
super.setValue(newVal)
notifyObservers()
}
}
trait MemorySensorObserver[T] extends AbstractObserver[MemorySensorSubject[T], MemorySensorObserver[T]]
并且你可以做到
def test(): Unit = {
val sensor = new MemorySensorSubject[Int]
val observer = new MemorySensorObserver[Int] {
override def notifyObserver(subject: MemorySensorSubject[Int]): Unit = {
println(s"New value of $subject is ${subject.value}")
}
}
sensor.register(observer)
sensor.setValue(42)
}
,输出将是
so.Main$MemorySensorSubject@363ee3a2的新值是42
这里最重要的可能是MemorySensorSubject
是一个明确命名的类型,因此可以在F-bound generic constraint中用作S