As it says, you can't do this, and for good reason. You can't prove you'll keep your promise. Consider this:
class AnotherSubclass: Class {}
let x = AnotherSubclass().instance
So x
should be AnotherSubclass
according to your protocol (that's Self
). But it'll actually be Subclass
, which is a completely different type. You can't resolve this paradox unless the class is final
. This isn't a Swift limitation. This limitation would exist in any correct type system because it allows an type contradiction.
On the other hand, something you can do is promise that instance
returns some consistent type across all subclasses (i.e. the superclass). You do that with an associated type:
protocol Protocol {
typealias InstanceType
var instance: InstanceType {get}
}
class Class: Protocol {
var instance: Class {return Subclass()}
}
class Subclass: Class {}
class AnotherSubclass: Class {}
let x = AnotherSubclass().instance
Now x
is unambiguously of type Class
. (It also happens to be random other subclass, which is kind of weird, but that's what the code says.)
BTW, all of this usually suggests that you're using subclassing when you really shouldn't be. Composition and protocols would probably solve this problem better in Swift. Ask yourself if there's any reason that Subclass
needs to actually be a subclass of Class
. Could it be an independent type that conforms to the same protocol? All kinds of problems go away when you get rid of subclasses and focus on protocols.
I've been thinking about this more, and there may be a way to get what you're looking for. Rather than saying that all subclasses implement instance
, attach instance
as an extension. You can still override that if you want to return something else.
protocol Protocol {
init()
}
class Class: Protocol {
required init() {}
var instance: Class { return Subclass() }
}
extension Protocol {
var instance: Self { return self.dynamicType.init() }
}
class Subclass: Class {}
This dodges the inheritance problem (you can't create the same "AnotherClass
returning the wrong type" this way).
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…