2014-12-03 74 views
0
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 
} 

我想让Zed类拥有一个适用于Bar和Baz类的属性。这可能吗?快速继承问题

+0

所以你想访问Bar和Baz类的'parent'? – Padarom 2014-12-03 07:56:59

+0

'parent'应该是'Bar'或'Baz'类。 – switz 2014-12-03 07:59:12

+1

那什么不起作用?这对我来说看起来很好...... – Grimxn 2014-12-03 08:15:23

回答

0

我不明白的问题,因为这段代码看起来好像没什么问题:

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 

如果问题是如何确保美孚的没有其他子类允许为捷思锐的父母:有没有办法来指定斯威夫特的类型约束的“或”约束,但你可以通过在酒吧和巴兹相同的协议,并指定该协议为parent的类型:

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() 
    } 
} 

这样ÿ您可以明确列出Zed支持的类(但这是一个非常糟糕的API设计;您应该发布协议,并让任何愿意遵守该协议的人遵守)。

+0

我想我有另一个问题。我清理了代码,它按预期工作,谢谢! – switz 2014-12-03 08:43:04

0

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

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

class Foo { 
    var str = "hi" 

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

美孚现在符合FooProtocol,即使它不直接实现它。这样,每个从Foo继承的类也符合该协议。现在

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

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

,你应该能够在捷思锐设定的parent类型FooProtocol。它可能是Bar或Baz的一个实例。

class Zed { 
    var parent: FooProtocol? 
} 
+0

如果你继承了父类的子类,为父类创建一个协议是不是很没用? – 2014-12-03 08:19:41

+1

这不是,如果你不想在每个子类中实现'refresh()'。 – Padarom 2014-12-03 08:23:56

+1

你不必在每个子类中重新实现它! Bar和Baz从foo继承它,即使没有协议涉及,并且从Foo继承是一个充足的类型约束。换句话说,问题中的代码就足够了。我怀疑实际的问题是如何防止Foo的其他子类被用作“父”,在这种情况下使用这样的协议是一种解决方案。 – 2014-12-03 08:28:12