【问题标题】:Swift: Can I return a private type that implements a public class and conforms to a public protocol?Swift:我可以返回实现公共类并符合公共协议的私有类型吗?
【发布时间】:2016-02-04 07:27:32
【问题描述】:

在 Objective-C 中,函数能够返回实现公共类和公共协议的私有类型的实例,而无需定义符合该协议的公共类。

例如假设我有这个头文件:

@protocol Flyer <NSObject>
-(void) fly;
@end

@interface Animal : NSObject
-(void) eat;
@end

Animal<Flyer> * randomFlyingAnimal();

还有这个实现文件:

@implementation Animal

-(void) eat {
    NSLog(@"I'm eating");
}

@end

@interface Bird : Animal<Flyer>
@end

@implementation Bird

-(void) fly {
    NSLog(@"I'm a flying bird");
}

@end

@interface Bat : Animal<Flyer>
@end

@implementation Bat

-(void) fly {
    NSLog(@"I'm a flying bat");
}

@end

Animal<Flyer> * randomFlyingAnimal() {
    switch (arc4random() % 2) {
        case 0:
            return [[Bird alloc] init];
        case 1:
        default:
            return [[Bat alloc] init];
    }
}

在此示例中,我的代码的使用者实际上并不知道 Bird 类或 Bat 类(或任何其他实现 Animal 并符合 Flyer 的类型),但可以确定从randomFlyingAnimal 返回的对象既可以是eat,也可以是fly

这样的事情在 Swift 中是可能的吗?

【问题讨论】:

  • 问得好问题,但您可以在操场上通过最少的代码转换简单地尝试...
  • 我已经修改了我的问题,以便更清楚我的实际意图。我知道在 Swift 中,如果我要公开定义一个派生自 Animal 并符合 Flyer 的类,我可以返回任何该类型的私有子类。但是,如果不存在实现 Animal 并符合 Flyer 的公共类型,我不确定方法的签名是什么。

标签: swift inheritance swift-protocols


【解决方案1】:

您可以在 Swift 中应用一些方法,但您可能会定义一个协议 AnimalType 和一个协议 FlyerType - 它们彼此之间没有关系:

public protocol AnimalType {}
public protocol FlyerType {
    func fly()
}

然后,如下创建内部或私有类:

internal class Animal: AnimalType {}
internal class Bird: Animal {}
internal class Bat: Animal {}

现在,类BirdBat 通过继承其基类Animal 符合AnimalType。为了也符合FlyerType,我们可以扩展这些类如下:

extension Bird: FlyerType {
    internal func fly() { print("Bird's flying") }
}

extension Bat: FlyerType {
    internal func fly() { print("Bat's flying") }
}

你的工厂函数可以如下实现:

public func randomFlyingAnimal() -> protocol<AnimalType, FlyerType> {
    switch (arc4random() % 2) {
    case 0: return Bird()
    default: return Bat()
    }
}

protocol&lt;AnimalType, FlyerType&gt;protocol composition type - 在这种情况下,它的应用程序似乎很有用。

【讨论】:

  • 这将返回一个符合 Animal 类所遵循的协议的对象。它实际上并没有返回 Animal 子类。当我想要返回一个派生自我无权修改的类的对象时,Objective-C 功能很有用,但允许我确保它仍然符合我的新协议。例如。我可以返回并存储一个指向 UIView * 的指针,并且任何从 UIView 派生并符合 MyCustomProtocol 的类型都可以。
  • @guy 也许你可以解释一下,返回一个同时符合AnimalTypeFlyerType 的对象和返回一个派生自类Animal 并符合FlyerType 的对象有什么区别。从客户端的角度来看,我没有看到 - 前提是协议 AnimalType 公开与类 Animal 相同的 API。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2014-01-03
  • 2013-04-05
  • 2014-11-20
  • 2011-07-21
  • 2013-07-26
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多