Ios 快速继承问题

Ios 快速继承问题,ios,class,swift,Ios,Class,Swift,我希望Zed类有一个同时适用于Bar和Baz类的属性。这是可能的吗?我能想到的最接近的方法是对父类使用 class Foo { var str = "hi"; func refresh() { println(self.str); } } class Bar: Foo { // override str in init // create Zed with parent = self } class Baz: Foo { // override str in

我希望Zed类有一个同时适用于Bar和Baz类的属性。这是可能的吗?

我能想到的最接近的方法是对父类使用

class Foo {
  var str = "hi";

  func refresh() {
    println(self.str);
  }
}

class Bar: Foo {
  // override str in init
  // create Zed with parent = self
}

class Baz: Foo {
  // override str in init
  // create Zed with parent = self
}


class Zed {
  var parent: Foo?; // I want it to work for both Bar and Baz

  // call parent.refresh() in init
}
Foo现在符合Foo协议,即使它没有直接实现它。这样,从Foo继承的每个类也都符合协议

protocol FooProtocol {
  var str: String { get set }
  func refresh()
}

class Foo {
  var str = "hi"

  func refresh() {
    println(self.str)
  }
}
现在,您应该能够将Zed中的
父项的类型设置为
FooProtocol
。然后它可以是Bar或Baz的一个实例

class Bar: Foo, FooProtocol {
  override init() {
    super.init()
    self.str = "ho"
  }
}

class Baz: Foo, FooProtocol {
  override init() {
    super.init()
    self.str = "hup"
  }
}

我不理解这个问题,因为我觉得这段代码很好:

class Zed {
  var parent: FooProtocol?
}
如果问题是如何确保不允许Foo的其他子类成为Zed的父类:无法在Swift的类型约束中指定“或”约束,但您可以在Bar和Baz中采用相同的协议,并将该协议指定为
父类
的类型:

class Foo {
    var str = "hi";

    func refresh() {
        println(self.str);
    }
}

class Bar: Foo {
    override init () {
        super.init()
        str = "bar"
        let zed = Zed(parent: self)
    }
}

class Baz: Foo {
    override init () {
        super.init()
        str = "baz"
        let zed = Zed(parent: self)
    }
}


class Zed {
    var parent: Foo?; // I want it to work for both Bar and Baz

    init(parent: Foo) {
        self.parent = parent
        self.parent?.refresh()
    }
}

let b = Bar() // prints bar

let c = Baz() // prints baz

通过这种方式,您可以显式地列出Zed支持的类(但这是一个非常糟糕的API设计;您应该发布协议,并让任何想要这样做的人都遵守该协议).

那么您想从Bar和Baz类访问
parent
parent
应该是
Bar
Baz
类。那么什么不起作用呢?在我看来,这很好…无论什么不起作用,问题不在这段代码中。在Bar或Baz的init中设置str也不是问题。因为根据我的游乐场,这完全符合预期。如果你对父类进行子类化,那么为父类创建一个协议不是很无用吗?如果你不想在每个子类中实现
refresh()
。你不必在每个子类中重新实现它!Bar和Baz从foo继承它,即使不涉及协议,并且从foo继承是一个足够的类型约束。换句话说,问题中的代码就足够了。我怀疑实际的问题是如何防止Foo的其他子类被用作父类,在这种情况下,使用这样的协议是一种解决方案。如果不在子类中实现
refresh()
,则该类不符合要求
refresh()
的协议。但你不是这么做的。您可以为符合协议的类创建子类。用
类栏:FooProtocol
替换
类栏:Foo
可能有意义,但在您的示例中,这是毫无意义的。Bar和Baz继承自Foo,后者已经实现了
刷新()
。这就是我可以访问此方法的原因,也是它符合
FooProtocol
的原因。它在我的操场上起作用了。一个改变可能是不在Foo中实现该协议,而是只在Bar和Baz中实现。那样的话,你就无法得到一个
Foo
的实例来适应你的父母。我想我还有另一个问题。我清理了代码,它按预期工作,谢谢!
protocol CanRefresh
{
    func refresh()
}

extension Bar : CanRefresh
{

}

extension Baz : CanRefresh
{

}

class Zed {
    var parent: CanRefresh?; // I want it to work for both Bar and Baz

    init(parent: CanRefresh) {
        self.parent = parent
        self.parent?.refresh()
    }
}