i have a base class with a private memberwise init, and a public convenience init:
public
class Base
{
let a:[Int]
let b:[Int]
let c:[Int]
private
init(a:[Int], b:[Int], c:[Int])
{
self.a = a
self.b = b
self.c = c
}
public convenience required
init(x:[Int])
{
...
self.init(a: a, b: b, c: c)
}
public
func f()
{
...
}
}
now i want to define subclasses that adds no stored properties but overrides some of the virtual class members. however, this requires duplicating the implementation of init(x:), since a subclass init cannot call a superclass convenience init.
public final
class Subclass:Base
{
public required
init(x:[Int])
{
...
super.init(a: a, b: b, c: c)
}
public override
func f()
{
...
}
}
one way to to satisfy the compiler error is to make the superclass init(x:) a designated initializer. however a designated init cannot call another designated init, which means it cannot delegate to the memberwise init, instead it must assign to the instance properties from within the body of the complex init.
are there any better ways to work around this restriction?
1 Like
tera
2
Not an answer below (I believe Swift can't do this but I'd love to be mistaken).
Is this checked? I don't see it is:
public class Base {
let a, b, c: [Int]
private init(a: [Int], b: [Int], c: [Int]) {
self.a = a; self.b = b; self.c = c
}
public convenience required init(x: [Int]) {
self.init(a: x, b: x, c: x)
}
public func f() {}
}
public final class Subclass: Base {
public override func f() {}
}
let x = Subclass(x: [])
print(x) // Base !?!
Note that this triggers a serious foot-gun in the language... I'd rather see a compilation error here (if there's no better way), or, it somehow "works correctly" i.e. prints "Subclass".
I don’t think it’s a problem in reflection per se, it’s literally instantiating the wrong class. Yes, it could be a similar problem although the latter appears to be an optimizer bug. I’ll try to take a look.
1 Like
tera
6
The former is also -O only, BTW.
Edit: adding a crashing scenario. Same as above plus:
public final class Subclass: Base {
var y: String = "Hello, World! 123"
public override func f() {}
}
let x = Subclass(x: [])
print(x) // Base in `-O` !?!
print(x.y) // 💣 CRASH
1 Like
no worries, happens to the best of us!