我有两个库类,Item
和ItemFood : Item
(从Item
派生),还有一个库函数registerItem(item: Item, name: String)
。我无法修改它们。
我有两个自己的类(ItemKey : Item
和ItemBerry : ItemFood
),它们是从库类派生的。
我想要的是将name: String
属性存储在我的类ItemKey
和ItemBerry
中,并使其作为“ NamedItem
”计数,因此我可以编写一个函数像这样:
fun registerNamedItem(namedItem: NamedItem) {
registerItem(namedItem, namedItem.name)
}
我不能仅仅像这样创建一个类:class NamedItem(val name: String) : Item
并从中派生我的类,因为有时我需要从ItemFood
派生我的类,而不是从Item
派生我的类。
我不想创建类似class NamedItem(val item: Item, val name: String)
的类包装器,因为那样的话,每次我想获取“底层” Item
时,我都需要手动获取item
属性:registerItem(namedItem.item, namedItem.name)
,这很丑。
我不能使用interface INamedItem { val name: String }
并在ItemKey
和ItemBerry
中实现此接口,因为那样我就需要以这种方式编写函数:
fun registerNamedItem(item: Item, namedItem: INamedItem) {
registerItem(item, namedItem.name)
}
,这根本没有改善。
是否存在某种先进的技术-使用接口,委托,泛型或其他方式-因此我可以按自己的意愿实现registerNamedItem
函数-将{的实例传递给registerItem(item: Item, name: String)
将{1}}作为第一个参数并将NamedItem
作为第二个参数?
答案 0 :(得分:0)
实际上,您可以为此使用界面:
fun main() {
registerNamedItem(ItemKey("item_key"))
registerNamedItem(ItemBerry("item_berry"))
}
// Cannot change this
open class Item
// Cannot change this
open class ItemFood : Item()
// This is your class
class ItemKey(override val name: String) : NamedItem()
// This is also your class
class ItemBerry(override val name: String) : NamedFoodItem()
// This is the property you would like to enforce
interface INamedItem {
val name: String
}
// Since Item and ItemFood are concrete classes, you don't have much choice there
abstract class NamedItem : Item(), INamedItem
abstract class NamedFoodItem : ItemFood(), INamedItem
// Adapter pattern
fun registerNamedItem(namedItem: NamedFoodItem) {
registerItem(namedItem, namedItem.name)
}
// Adapter pattern
fun registerNamedItem(namedItem: NamedItem) {
registerItem(namedItem, namedItem.name)
}
fun registerItem(namedItem: Item, name: String) {
println("Item $namedItem registered with $name")
}
在您的情况下,委托不起作用,因为从您的示例中来看,Item
是一个类,并且您只能委托给接口。