最初的例子是不合适的,正如有些人指出的那样(我现在同意,谢谢)。所以我提出了一个新的,一个更复杂的。顺便说一下,如果你能帮助我在更抽象的层面上理解这一点,我将非常感激。
class Employee {
var department :Department? = nil
func leader() -> Employee {
return self.department!.director
}
}
class Designer :Employee {
func design() {
// Draw some blueprint
}
}
class Developer :Employee {
func develop() {
// Write some code
}
}
class Department <E: Employee> {
let employees :[E]
let director :E
init(employees :[E], director :E) {
self.employees = employees
self.director = director
for e in self.employees {
e.department = self
}
}
}
我正在实施类似纸牌游戏的东西。
class Suit <C :Card> {
public let cards :[C]
init(cards :[C]) {
self.cards = cards
}
convenience
init() {
self.init(cards: Array(1...13).map({ C(faceValue:$0) }))
for card in self.cards {
card.suit = self
}
}
}
class Card {
public let faceValue :UInt
public internal(set) var suit :Suit? = nil
required
init(faceValue :UInt) {
self.faceValue = faceValue
}
}
我希望每张卡都有一个参考回到它所属的套装。 我面临的问题是套装是一个通用类。 所以,我有这个错误:
有什么想法来解决这个问题?感谢
答案 0 :(得分:1)
你所拥有的是部分多态的,部分是通用的。要使其工作,请将通用部分(部门及其可包含的内容)与多态部分(Employee类层次结构)分开。
快速修复
// A protocol to define what the department can hold:
protocol Employable {
weak var department :Department<Self>? { get set }
}
// A generic department to hold objects that conform to the Employable protocol:
class Department <E: Employable> {
let employees :[E]
let director :E
init(employees :[E], director :E) {
self.employees = employees
self.director = director
for var e in self.employees {
// e is defined as var rather than defaulting to let
e.department = self
}
}
}
// The polymorphic Employee hierarchy:
class Employee : Employable {
weak internal var department: Department<Employee>?
func leader() -> Employee {
return self.department!.director
}
}
class Designer :Employee {}
class Developer :Employee {}
这可以让您的示例发挥作用,但现在您可以更进一步。
使用通用集合
将Employable和Department重命名为generic:
protocol MyCollectable {
weak var collection :MyCollection<Self>? { get set }
}
class MyCollection <E: MyCollectable> {
let members :[E]
let leader :E
init(members :[E], leader :E) {
self.members = members
self.leader = leader
for var e in self.members{
e.collection = self
}
}
}
现在你可以这样做:
class Employee : MyCollectable {
weak internal var collection: MyCollection<Employee>?
func leader() -> Employee {
return self.collection!.leader
}
}
class Designer :Employee {}
class Developer :Employee {}
var department = MyCollection<Employee>(members: [Designer()], leader: Designer())
和此:
class Canine : MyCollectable {
weak internal var collection: MyCollection<Canine>?
}
class Wolf : Canine {}
class Dog : Canine {}
var pack = MyCollection<Canine>(members: [Wolf(),Dog()],leader: Wolf())
var wolfPack = MyCollection<Wolf>(members: [Wolf(),Wolf()], leader: Wolf())
但是你受到了保护:
var wolfPack = MyCollection<Wolf>(members: [Wolf(),Dog()], leader: Wolf())
或者这个:
var wolfPack = MyCollection<Wolf>(members: [Wolf(),Designer()], leader: Wolf())
<强>更新强>
替代使用收集协议和可收集
protocol MyCollectable {
associatedtype MyCollection
var collection :MyCollection? { get set }
}
protocol MyCollection {
associatedtype MyCollectable
var members:[MyCollectable] { get }
var leader:MyCollectable { get }
}
class Employee : MyCollectable {
typealias MyCollection = Department
internal var collection: Department?
}
class Department : MyCollection {
typealias MyCollectable = Employee
let members :[MyCollectable]
let leader :MyCollectable
init(members :[MyCollectable], leader :MyCollectable) {
self.members = members
self.leader = leader
for e in self.members{
e.collection = self
}
}
}
class Designer:Employee {}
class Developer:Employee {}
var dept = Department(members: [Designer(), Designer()],leader: Developer())
最后,请注意,除非管理对象,否则反向引用是一个坏主意,例如通过核心数据存储,其中后向引用是反向关系。