gpt4 book ai didi

arrays - Swift - 具有特定类类型的数组

转载 作者:行者123 更新时间:2023-11-28 06:10:42 25 4
gpt4 key购买 nike

我如何创建数组来保存属于特定类的对象。

class BaseObject {}

class Derived1: BaseObject {}
class Derived2: BaseObject {}
class Derived2: BaseObject {}

我需要创建一个数组,其中只包含从 BaseObject 派生的对象

类似于 - var array : [BaseObject.Type] = []

有没有办法指定这个?

此外,我应该可以像这样使用它

if let derived1 = object as? [Derived1] {

}
else if let derived2 = object as? [Derived2] {

}

最佳答案

您显然可以将数组定义为 BaseObject 的数组:

var objects: [BaseObject] = []  // or `var objects = [BaseObject]()`

但它会让您创建异构集合(BaseObjectDerived1Derived2 或任何其他子类)。这是一个核心 OO 设计概念(Liskov substitution principle),BaseObject 的任何子类都应该(并且将会)被允许。

如果你只想说你只能有一个子类型的数组,你显然可以这样定义你的数组,例如:

var objects: [Derived1] = []

这显然只允许 Derived1 对象(以及 Derived1 的任何子类。


90% 的情况下,以上就足够了。但在某些情况下,您可能需要一些集合,其方法需要一些继承的基本行为,但您不想允许异构集合。在这种情况下,我可能会考虑更面向协议(protocol)的模式:

  1. 归根结底,我们应该进行子类化,还是应该使用面向协议(protocol)的方法? IE。 BaseObject 实际上是您为了自己的目的而实例化的东西,或者它只是为了定义子类的一些常见行为。如果是后者,协议(protocol)可能是更好的模式,例如:

    protocol Fooable {
    func foo()
    }

    // if you want, provide some default implementation for `foo` in an
    // protocol extension

    extension Fooable {
    func foo() {
    // does something unique to objects that conform to this protocol
    }
    }

    struct Object1: Fooable {}
    struct Object2: Fooable {}
    struct Object3: Fooable {}

    这会产生您可能一直在更面向对象的方法中使用的那种行为,但使用的是协议(protocol)。具体来说,您编写一个 foo 方法,所有符合此协议(protocol)的类型,例如 Object1Object2 等,都可以使用无需自己实现 foo(当然,除非你想这样做,因为它们出于某种原因需要特殊行为)。

  2. 因为这消除了子类化,这就为使用泛型和协议(protocol)打开了大门,这些泛型和协议(protocol)规定了一些普遍的行为,同时规定了成员的同质性。例如:

    struct FooCollection<T: Fooable> {
    private var array = [T]()

    mutating func append(_ object: T) {
    array.append(object)
    }

    // and let's assume you need some method for your collection that
    // performs some `Fooable` task for each instance

    func fooAll() {
    array.forEach { $0.foo() }
    }
    }

    这是一个泛型,它是符合您的协议(protocol)的同质对象集合。例如,当你去使用它时,你会声明一个特定类型的 Fooable 类型来使用:

    var foo = FooCollection<Object1>()

    foo.append(Object1()) // permitted
    foo.append(Object2()) // not permitted

    foo.fooAll()

现在,我之所以走这条路,是因为在其他地方的评论中,您询问的是泛型。如果(a)集合真的需要同质化,我个人只会走这条路; (b) 该集合还希望实现协议(protocol)共有的一些共享逻辑。否则,我可能会坚持使用简单的 [Derived1](或 [Object1])。以上内容在需要时可能很强大,但对于更简单的情况来说就有点过分了。

有关面向协议(protocol)编程、同质与异质行为、传统 OO 思维方式的传统绊脚石的更多讨论,建议您参阅 WWDC 2015 视频,Protocol-Oriented Programming in Swift ,或者它是 2016 companion video以 2015 年的视频为基础。

最后,如果您有任何其他问题,我建议您编辑您的问题,提供您尝试使用此模式解决的实际问题的详细信息。抽象的讨论往往没有成果。但是,如果您告诉我们您尝试使用问题中的模式解决的实际问题是什么,这将是一次更具建设性的对话。

关于arrays - Swift - 具有特定类类型的数组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46762392/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com