- Java 双重比较
- java - 比较器与 Apache BeanComparator
- Objective-C 完成 block 导致额外的方法调用?
- database - RESTful URI 是否应该公开数据库主键?
Swift 问题,比如说你有一个协议(protocol) Bark:
protocol MakeSound {
func bark()
}
一个父类(super class) Dog,实现了吠叫和游泳:
class Dog: MakeSound {
}
然后是不同类型的狗:
class Poodle: Dog {
}
class GermanShephard: Dog {
}
class SheepDog: Dog {
}
但是 Poodle 会狂吠,它们不会吠叫……所有的狗都会吠叫,只是它们的叫法不同……我如何赋予它们特定的吠叫行为?
扩展协议(protocol)?...
extension MakeSound {
func bark()
func yapper()
}
但是 Poodle 和德国牧羊犬都有这两种行为(一只狂吠的德国牧羊犬?!)
如果我进行 2 次扩展并使用 where Self = ? 检查类型类
extension MakeSound where Self: GermanShephard {
func bark() {
print("Bark")
}
}
extension MakeSound where Self: Poodle{
func yapper() {
print("yap yap")
}
}
但我只能检查一种类类型或狗类型。牧羊犬也会吠叫,但我无法在此处查看...
我知道在 Java 中,您可以使用多种不同的实现来扩展接口(interface)。你如何在 Swift 中使用协议(protocol)来解决这个问题?
最佳答案
如果我正确理解你的问题,也许这对你有帮助。
您可以通过扩展协议(protocol)为 bark() 提供默认实现。然后在符合协议(protocol)的其他类上,您可以更改 bark 函数的实现:
protocol Bark {
func bark()
}
//default implementation
extension Bark {
func bark() { print("Bark") }
}
class Dog: Bark {}
//By calling bark func in Poodle, you change the default implementation.
class Poodle: Dog {
func bark() { print("Yap") }
}
class GermanShephard: Dog {
func bark() { print("Woof") }
}
let dog = Dog()
let poodle = Poodle()
let germanShephard = GermanShephard()
dog.bark()
//Bark
poodle.bark()
//Yap
germanShephard.bark()
//Woof
你也可以不做任何默认实现,只为每种情况添加你自己的实现
评论后编辑:
这是协议(protocol)有用的主要原因之一。它们消除了与子类化相关的紧密耦合。这是一个基本示例,因为整个主题包含很多信息,但您可以创建协议(protocol) DogRepresentable 并分配所有狗实现相同的所有默认属性和功能,而不是将 Dog 子类化。然后你可以扩展 DogRepresentable where self: UIViewController 并实现默认功能:
protocol Barkable {
func bark()
}
protocol DogRepresentable: Barkable {
//properties and functions all dogs will have with same implementation
}
extension DogRepresentable where Self: UIViewController {
//default implementation for functions all dogs will use
}
通过将 Barkable 分配给 DogRepresentable,您知道任何符合 DogRepresentable 的类也必须符合 Barkable。
现在,当您将 DogRepresentable 分配给一个类时,它将获得基类将获得的所有默认实现,并且您被迫调用 bark() 函数以正确遵守协议(protocol):
class Dog: DogRepresentable {
func bark() { print("Bark") }
}
class Poodle: DogRepresentable {
func bark() { print("Yap") }
}
class GermanShephard: DogRepresentable {
//Won't conform because it doesn't have bark()
}
通过这种方式,您可以获得与基类一样的所有默认实现,但不会有忘记覆盖父类(super class)函数的问题。
根据第二条评论编辑 2:
在这种情况下,最好的办法是在不遵守 Barkable 的情况下保留 DogRepresentable,然后为不同类型创建协议(protocol):因此,如果您有爱吠叫的狗,您可以制定一个具有吠叫功能和默认实现的协议(protocol) Yappable。然后你可以有另一个协议(protocol) Barkable 有它自己的树皮函数和它自己的默认实现。然后让类符合它们应该符合的协议(protocol)。 Poodle 符合 Yappable,Dog 符合 Barkable。
通过创建这些单独的协议(protocol),您可以将针对每种情况的功能保留在一个地方,并且只使用您需要的任何一个,从而使您的代码更干净、更具可读性和 DRY。
关于swift - 扩展协议(protocol)以实现不同的行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41161013/
internal protocol Reducer { associatedtype S : BaseState associatedtype A : BaseActi
我在考虑我的应用程序中的验证检查,我认为在任何模型上调用 ValidatorFactory,实现 Validee,这意味着说哪个类负责 ValidatorCreation 听起来不错。但是下面的代码不
我已经定义了 2 个协议(protocol)。我需要第一个 (NameProtocol) 来执行 Equatable 协议(protocol)。而另一个类 (BuilderProtocol) 有一个返
在上传方面,WebDAV 协议(protocol)在哪些方面优于 HTTP 协议(protocol)。 Socket Upload 协议(protocol)和 WebDav Upload 协议(pro
是否可以在任何版本的 Swift 中扩展具有混合类/协议(protocol)类型约束的协议(protocol)?例如,仅当 Self 是 UIViewController 的子类并且符合 Protoc
我有一个协议(protocol) (ProtocolA),其中包含符合第二个协议(protocol) (ProtocolB) 的单个属性。 public protocol ProtocolA {
NSObject 协议(protocol)带有常用的协议(protocol)模板,但它似乎并不是协议(protocol)实际实现所必需的。将其排除在外似乎完全没有任何改变。那么,协议(protocol
我想根据这两种协议(protocol)的一般特征(例如开销(数据包)、安全性、信息建模和可靠性)来比较 OPC UA 和 MQTT。我在哪里可以找到每个协议(protocol)的开销和其他特性的一些示
使用 Swift 4,我正在尝试编写一个自定义协议(protocol),它提供对 @objc 协议(protocol)的一致性。 一些代码 更具体地说,我有一个自定义协议(protocol) Sear
我想定义一个在 Viper 架构中使用的协议(protocol),以使用具有弱属性的协议(protocol)在 Viper 组件之间建立连接,但我收到以下错误消息: 'weak' may only b
我在同一个网络中有 3 个 docker 容器: 存储 (golang) - 它提供了用于上传视频文件的 API。 主播 (nginx) - 它流式传输上传的文件 反向代理 (姑且称之为代理) 我有
我打算在我的项目中使用 php socket。它需要用户登录才能根据 session 填充内容。所以我的问题是,TCP/IP 协议(protocol)也像 HTTP 协议(protocol)一样为每个
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
目前,我的网站有两个版本。一种带有 https://-证书,一种没有。我想将我网站的 http 版本上的所有用户 301 重定向到我网站的 https://版本。 这似乎不可能,因为创建重定向将导致重
我有一个 Swift View Controller ,它定义了一个在 Objective-C View Controller 中应该遵循的协议(protocol): ChildViewControl
我在客户那里有数百个硬件设备,需要通过telnet接口(interface)发送HTTP数据。 目标是等待数据的 Apache 2 Web 服务器和 PHP 脚本。 这已经可以正常工作了,但是我们发现
我发现如果我创建一个这样的协议(protocol): protocol MyProtocol { } 我不能这样做: weak var myVar: MyProtocol? 我找到了解决这个问题的方法
Xcode 基于模板生成了这个头文件: // this file is XYZAppDelegate.h #import @interface XYZAppDelegate : UIRespond
我在 github 中有一个公开的存储库,我正在开发一个开源应用程序,用于制作产品目录和小型 cms 内容。 我还有一个私有(private)仓库(不托管在github),它是在托管在github的开
您好,我想让别人看到私有(private) repo 代码,但不想公开我的 repo ,也不希望他们有能力更改内容。这可能吗?我查看了网站的“管理”部分,但没有找到合适的内容。谢谢大家。 最佳答案 据
我是一名优秀的程序员,十分优秀!