/ / Scala: Как да вмъкнем SubClass вместо Superclass в Map, обявен за SuperClass - scala, class

Scala: Как да вмъкнете SubClass вместо Superclass в Map, обявен за SuperClass - scala, class

Имам изискване да използвам подклас в aHashMap, който е обявен за SuperClass. Например: Създадох суперклас и подклас. Сега създавам абстрактен клас А и конкретен клас В, който разширява А. А има променлива myMap, която е декларирана като java.util.Map[_ <: Superclass, String] , В клас B трябва да използвам myMap, но трябва да вмъкна инстанция на SubClass вместо Superclass в myMap.following е кодът за обяснение

abstract class Superclass {
def foo(value:String): Boolean
}



class Subclass extends Superclass {
def foo(value:String) = {
true // or random boolean expression
}
}

abstract class A {
var myMap: java.util.Map[_ <: Superclass, String]
def addToMap(value:String)
}

class B extends A {
myMap = new java.util.HashMap[Subclass, String]()

def addToMap(value:String) {
val subclass = new SubClass()
myMap.put(subclass, value) // getting compilation error here
}
}

Ако се опитам да вмъкна потребителския подклас в myMap, получавам следната грешка: несъответствие на типа; found: Необходим е Subclass.type (с подклас): _ $ 2 където _ _ ​​$ 2 <: SuperClass

Отговори:

2 за отговор № 1

Ако можете да използвате SubClass тук бихте нарушили принципа на заместването на Лисков: клас B трябва да бъде в състояние да направи всичко, което може да се направи с A, но в примера ти не можеш да правиш неща SuperClass ключовете в него Map.

Има няколко начина около него, напр. можете да параметризирате A и B:

abstract class A[S <: Superclass] {
var myMap: java.util.Map[S, String]

def addToMap(value: String)
}

class B extends A[Subclass] {

var myMap:java.util.Map[Subclass, String] = new java.util.HashMap[Subclass, String]()

def myMap(map: java.util.Map[Subclass, String]) { myMap = map }

def addToMap(value: String) {
val subclass = new Subclass()
myMap.put(subclass, value)
}
}

Подобно решение би могло да използва членове с абстрактен тип:

abstract class A {

type S <: Superclass

var myMap: java.util.Map[S, String]

def addToMap(value: String)
}

class B extends A {

type S = Subclass

var myMap: java.util.Map[Subclass, String] = new java.util.HashMap[Subclass, String]()

def myMap(map: java.util.Map[Subclass, String]) {
myMap = map
}

def addToMap(value: String) {
val subclass = new Subclass()
myMap.put(subclass, value)
}
}

Не съм сигурен защо се изисква допълнителен сетер.

Като цяло мисля, че поставям var в абстрактен клас не е добра идея. Трябва ли детайл за изпълнението да изтече така? Вероятно не. И дори ако е необходимо, наистина ли трябва да бъдеш в състояние замени пълната карта? Ако не, можете да използвате a val, Или можете да изградите фасада за добавяне, премахване, търсене на елементи, които използвате defи, без изобщо да споменем картата в A.