ios - 如何将方法的返回类型编写为符合协议+ 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 运行时失败:类型转换失败
解决方案
你的意思是这样的吗?
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
}
推荐阅读
- webrtc - 简单对等不同网络调用问题
- python - 正则表达式 .*(\d+x\d+)$ 必须是贪心的
- angular - 更改页面后复选框列表保持初始状态
- python - 无法运行程序“python3”
- java - Java中的Apache Spark - Gradle没有下载jar文件
- scala - Scala:模式匹配与 if-else
- phpmyadmin - OS X - 禁止 - 您无权访问此服务器上的 /phpmyadmin/setup
- c# - 如何在c#变量中分配双引号
- ruby-on-rails - 在 docker 上加载应用程序代码之前运行 rails assets:precompile
- javascript - 如何从 chart.googleapis.com url 中提取 url 参数