Swift 协议与 Kotlin 抽象类不同。更接近的比较是 Kotlin interface 和 Swift protocol。
我对您的要求有点困惑。但是,根据我在这里看到的情况,Protocol Oriented Programming 似乎是一个很好的案例,它可以减少对多个嵌套抽象类或子类的需求。
我也有点困惑,为什么您需要获取 DeviceType.... 的 DeviceType 是 DeviceType 本身而不是 DeviceType?
在我看来,这样的事情似乎要简单得多:
科特林
见Kotlin playground
interface Device {
fun doSomething()
}
interface MobileDevice: Device {
fun onTap()
}
interface DesktopDevice: Device {
fun onClick()
}
interface WearableDevice: Device {
fun onButtonPush()
}
class AndroidPhone: MobileDevice {
override fun doSomething() {
println("I'm an Android phone.")
}
override fun onTap() {
println("Tap the screen.")
}
}
class MacDesktop: DesktopDevice {
override fun doSomething() {
println("I'm a Mac desktop.")
}
override fun onClick() {
println("Click the magic mouse.")
}
}
class SmartNecklace: WearableDevice {
override fun doSomething() {
println("I'm a smart necklace.")
}
override fun onButtonPush() {
println("Help! I've fallen and I can't get up!")
}
}
可以这样使用:
fun exampleFunction() {
val mobile = AndroidPhone()
val desktop = MacDesktop()
val wearable = SmartNecklace()
mobile.doSomething()
desktop.doSomething()
wearable.doSomething()
val devices = listOf(mobile, desktop, wearable)
devices.forEach { device ->
when (device) {
is MobileDevice -> device.onTap()
is DesktopDevice -> device.onClick()
is WearableDevice -> device.onButtonPush()
else -> println("Unknown Type.")
}
}
}
斯威夫特
在您的 Swift 版本中,您还可以添加一些 default behaviors to the protocols(请参阅下面的协议扩展示例)。
protocol Device {
func doSomething()
}
protocol MobileDevice: Device {
func onTap()
}
protocol DesktopDevice: Device {
func onClick()
}
protocol WearableDevice: Device {
func onButtonPush()
}
extension Device {
func doSomething() {
print("Doing default thing.")
}
}
extension WearableDevice {
func onButtonPush() {
print("Help! I've defaulted and I can't get up!")
}
}
class AndroidPhone: MobileDevice {
func onTap() {
print("Tap the screen.")
}
}
class MacDesktop: DesktopDevice {
func doSomething() {
print("I'm a Mac desktop.")
}
func onClick() {
print("Click the magic mouse.")
}
}
class SmartNecklace: WearableDevice {
func doSomething() {
print("I'm a smart necklace.")
}
}
可以这样使用:
func exampleFunction() {
let mobile = AndroidPhone()
let desktop = MacDesktop()
let wearable = SmartNecklace()
mobile.doSomething()
desktop.doSomething()
wearable.doSomething()
let devices: Array<Device> = [mobile, desktop, wearable]
devices.forEach { device in
switch (device) {
case let device as MobileDevice:
device.onTap()
case let device as DesktopDevice:
device.onClick()
case let device as WearableDevice:
device.onButtonPush()
default:
print("Uknown type")
}
}
}
输出
Doing default thing.
I'm a Mac desktop.
I'm a smart necklace.
Tap the screen.
Click the magic mouse.
Help! I've defaulted and I can't get up!
如果你做了这样的事情,你就已经知道对象的性质(如 switch/when 块所示)。您不需要获取设备类型的方法。你会得到它。
如果我在您的问题中遗漏了什么,请告诉我。
至于你的错误:
Swift runtime failure: type cast failed
如果演员阵容失败,我猜type1DeviceType 是DeviceTypeProtocol,而不是DeviceTypeProtocol.Type。
public func getDT() -> DeviceTypeProtocol.Type {
return type1DeviceType as! DeviceTypeProtocol
}
检查当您尝试输入或使用 type1DeviceType 时显示的类型,或查看其快速帮助以查看类型。当你到达那个点时,你认为实际的类型是什么?
我还想问,以与 Android 版本完全相同的方式执行此操作有多重要?我总是建议正确规划跨平台,以使事情尽可能相似。它总是有帮助的,尤其是在作为一个团队一起调试和构建事物时。
从上面的代码可以看出,它几乎是准确的。这也是我做事的方式。但不能以完成工作为代价。