首页 > 解决方案 > 如何将方法的返回类型编写为符合协议+ swift的类

问题描述

我正在做一个项目,我需要在 iOS 中使用 swift 复制使用 android 开发的功能。

在android应用程序中,有一个地方提到了抽象类Device内方法的返回类型,

abstract fun getDT(): Class<out DeviceType>

其中 DeviceType 本身就是另一个抽象类。所以我从android开发者那里听说,在这个方法的实际实现中,它会返回一个继承DeviceType的类,如下所示,

override fun getDT(): Class<out DeviceType> {
    return type1DeviceType::class.java
}

其中 type1DeviceType 实际上继承了 DeviceType 抽象类,如下所示

public class type1DeviceType extends DeviceType {

所以在我们的 iOS 术语中,抽象类的等价物是协议。

所以在 iOS 中,我编写了一个协议来代替 Android 中的抽象类。而对于其中抽象函数的返回类型,我需要提到返回类型是符合DeviceType协议的东西。知道如何实现这一目标吗?

我在swift中尝试了以下代码。

 public func getDT() -> DeviceTypeProtocol.Type {
    return type1DeviceType as! DeviceTypeProtocol.Type
}

但是在运行时,我得到了错误,

Swift 运行时失败:类型转换失败

标签: iosswiftkotlinprotocolsabstract

解决方案


你的意思是这样的吗?

protocol DeviceType {
    func getDeviceType() -> DeviceType.Type
}

extension DeviceType {
    func getDeviceType() -> DeviceType.Type { Self.self }
}



class AudioDevice: DeviceType {
    func getDeviceType() -> DeviceType.Type { AudioDevice.self }
}

class Microphone: AudioDevice {
}

class Speaker: AudioDevice {
    override func getDeviceType() -> DeviceType.Type { Speaker.self }
}



class VideoDevice: DeviceType {}

class Camera: VideoDevice {}

class Monitor: VideoDevice {
    func getDeviceType() -> DeviceType.Type { VideoDevice.self }
}


func test() {
    print(AudioDevice().getDeviceType()) // prints AudioDevice
    print(Microphone().getDeviceType()) // prints AudioDevice
    print(Speaker().getDeviceType()) // prints Speaker
    print(VideoDevice().getDeviceType()) // prints VideoDevice
    print(Camera().getDeviceType()) // prints Camera
    print(Monitor().getDeviceType()) // prints VideoDevice
}

为 a 定义了一个协议,该协议DeviceType具有返回类型的能力,该类型getDeviceType也是 的类型DeviceType

您所描述的内容不需要扩展协议,但我想以任何一种方式进行演示。它用于VideoDevice.

所以AudioDevice继承了协议并明确定义了获取设备类型的方法。因为它返回的类型AudioDevice就是它打印出来的。Microphone继承自(AudioDevice不是从DeviceType)并且不覆盖该方法,因此它也返回AudioDevice。并且Speaker也继承自AudioDevice但确实覆盖了该方法,return 也是如此Speaker

VideoDevice更有趣一点。它继承了协议,但没有明确定义所需的方法。因此,它使用具有有趣语法的扩展名Self.self。如果这更有意义的话,它基本上只是意味着“返回动态自我的静态类型”......这只是可能的,因为定义了协议的扩展。删除扩展将创建一个编译时错误,让您知道您确实需要定义该方法。现在因为很好地定义了扩展名,所以VideoDevice已经打印出来了。Camera继承自VideoDevice(而不是继承自)也是如此DeviceType。然后Monitor再次覆盖该方法并打印出来VideoDevice而不是Monitor.

当然,您可以将设备类别(在本例中为视频和音频)定义为继承设备类型的协议。您还可以对这些协议进行扩展。看看这个例子:

protocol DeviceType {
    func getDeviceType() -> DeviceType.Type
}


protocol AudioDevice: DeviceType { }

class Microphone: AudioDevice {
    func getDeviceType() -> DeviceType.Type { Microphone.self }
}

class Speaker: AudioDevice {
    func getDeviceType() -> DeviceType.Type { Speaker.self }
}


protocol VideoDevice: DeviceType { }

extension VideoDevice {
    func getDeviceType() -> DeviceType.Type { Self.self }
}

class Camera: VideoDevice {
}
class Monitor: VideoDevice {
    func getDeviceType() -> DeviceType.Type { Camera.self }
}


func test() {
    print(Microphone().getDeviceType()) // prints Microphone
    print(Speaker().getDeviceType()) // prints Speaker
    print(Camera().getDeviceType()) // prints Camera
    print(Monitor().getDeviceType()) // prints Camera
}

推荐阅读