如何将方法的返回类型编写为符合协议+swift的类

Man*_*ano 5 protocols abstract ios kotlin swift

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

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

abstract fun getDT(): Class<out DeviceType>
Run Code Online (Sandbox Code Playgroud)

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

override fun getDT(): Class<out DeviceType> {
    return type1DeviceType::class.java
}
Run Code Online (Sandbox Code Playgroud)

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

public class type1DeviceType extends DeviceType {
Run Code Online (Sandbox Code Playgroud)

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

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

我尝试在 swift 中使用以下代码。

 public func getDT() -> DeviceTypeProtocol.Type {
    return type1DeviceType as! DeviceTypeProtocol.Type
}
Run Code Online (Sandbox Code Playgroud)

但在运行时,我收到错误,

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

Mat*_*lak 4

你的意思是这样的吗?

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
}
Run Code Online (Sandbox Code Playgroud)

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

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

因此AudioDevice继承了协议并明确定义了获取设备类型的方法。因为它返回的类型AudioDevice就是它打印出来的类型。继承MicrophoneAudioDevice(而不是继承自DeviceType)并且不会重写该方法,因此它也返回AudioDevice。并且Speaker也继承AudioDevice但重写该方法, return 也是如此Speaker

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

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

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
}
Run Code Online (Sandbox Code Playgroud)