Кажется, что вы хотите, по сути, типизированную карту. Совершенно очевидно, что то, что вы пытаетесь сделать, просто не может работать. Когда вы звоните get
, вы получаете PropertyAbstract[X]
для неизвестного X
(за исключением того, что это подтип A
). Как вы можете тогда предположить, что это займет B
с?
Решение состоит в том, чтобы ваш PropertyAbstract
был контравариантным , но это означает, что он не может быть изменяемой коллекцией каким-либо разумным способом (она может быть изменяемой, конечно, но Вы можете выйти, будет A
).
scala> class A; class B extends A; class C extends A
defined class A
defined class B
defined class C
scala> abstract class PropertyAbstract[-T] { val revs = new java.util.ArrayList[AnyRef] }
defined class PropertyAbstract
scala> class PropertyA extends PropertyAbstract[B]; class PropertyB extends PropertyAbstract[C]
defined class PropertyA
defined class PropertyB
scala> abstract class ClassAbstract {
| val props: Map[String, PropertyAbstract[_ <: A]]
| def get(prop: String) = (props get prop).get
| }
defined class ClassAbstract
scala> class Class extends ClassAbstract { val props = Map("prop1" -> new PropertyA, "prop2" -> new PropertyB) }
defined class Class
scala> val the_class = new Class
the_class: Class = Class@298508
scala> val proxied_prop = the_class.get("prop1")
proxied_prop: PropertyAbstract[_ <: A] = PropertyA@a269e2
scala> val direct_prop = the_class.props.get("prop1").get
direct_prop: PropertyAbstract[C with B] = PropertyA@a269e2
Следующая компиляция:
scala> proxied_prop.revs.add(new B)
res0: Boolean = true
scala> direct_prop.revs.add(new B)
res1: Boolean = true
Но, конечно, вы могли бы положить туда что угодно!
Возможно, вам стоит взглянуть на бесформенного Майлза Сабина для того, что вы можете делать с точки зрения разнородных коллекций.