如何处理 kotlin 中的多态性

ras*_*vap 2 polymorphism abstract-class kotlin

我正在使用一个抽象类和两个具体类,它们实现了抽象类。示意图如下: 在此处输入图片说明

我的课程看起来像:

abstract class NavItem() {
    var attributes: String = ""
    var text = ""
}

class NavMenu(val items: MutableList<NavItem>) : NavItem()

class NavLink(var shortText: String) : NavItem()
Run Code Online (Sandbox Code Playgroud)

问题是当我尝试处理可能是 NavMenu 或 NavLinks 的项目时,NavMenus 有一个 NavLinks 的集合。

我正在尝试使用多态作为下一个代码来处理这些项目:

navMenu.items.forEach{ item ->
            buildNavItem(item)
        }
Run Code Online (Sandbox Code Playgroud)

buildNavItem 方法似乎是:

private fun buildNavItem(navMenu: NavMenu){
        navMenu.items
        navMenu.attributes
        navMenu.items
    }

    private fun buildNavItem(navItem: NavItem){
        navItem.text
        navItem.attributes
    }

    private fun buildNavItem(navLink: NavLink){
        navLink.text
        navLink.attributes
    }
Run Code Online (Sandbox Code Playgroud)

但是代码总是进入 buildNavItem(navItem: NavItem),即使在 for each 中我有时可以看到该项目是 NavLink,或者是 NavMenu。

有什么建议吗?

谢谢!!

Ser*_*gey 5

这不是多态的工作原理。您有navMenu.items一个类型为 的列表MutableList<NavItem>,它可以存储NavItems 或其后代。在forEach函数中,您遍历每个具有NavItem类型和调用buildNavItem(item)函数的项目。在这种情况下buildNavItem(navItem: NavItem)总是被调用。要使用另一个参数调用相同的方法,您需要将其显式转换为该类型。我建议,这就是多态的工作原理,是buildNavItem()NavItem类中创建函数并在后代中实现它:

abstract class NavItem() {
    var attributes: String = ""
    var text = ""
    abstract fun buildNavItem()
}

class NavMenu(val items: MutableList<NavItem>) : NavItem() {
    override fun buildNavItem() {
        // ... your concrete implementation for NavMenu
    }
}

class NavLink(var shortText: String) : NavItem() {
    override fun buildNavItem() {
        // ... your concrete implementation for NavLink
    }
}
Run Code Online (Sandbox Code Playgroud)

然后你可以在forEach函数中调用它:

navMenu.items.forEach { item ->
        item.buildNavItem()
}
Run Code Online (Sandbox Code Playgroud)

在这种情况下,buildNavItem()将为存储在 中的正确对象调用函数navMenu.items,即,如果它是NavLink类型的对象NavLink,则将调用在类中重写的函数“buildNavItem()” 。