Super.init() called automatically?

Why does the following code compile?Why does Bar's init(x: Int) automatically
call Foo's init()?Why don't I have to manually call super.init() myself?
What passage
ofhttps://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Initialization.html#//apple_ref/doc/uid/TP40014097-CH18-ID203tells
me that this should be the case?
--------------------class Foo { init() { print("foo init")
}}class Bar: Foo { init(x: Int) { print("bar init") }}let b =
Bar(x: 0)//prints:// bar init// foo init

Why does the following code compile?
Why does Bar's init(x: Int) automatically call Foo's init()?
Why don't I have to manually call super.init() myself?

What passage of
The Swift Programming Language: Redirect
tells me that this should be the case?

Looks like a bug. Do you mind filing a bug report on bugs.swift.org?

-Joe

···

On May 16, 2016, at 7:09 AM, tuuranton--- via swift-users <swift-users@swift.org> wrote:

--------------------
class Foo {
    init() {
        print("foo init")
    }
}
class Bar: Foo {
    init(x: Int) {
        print("bar init")
    }
}
let b = Bar(x: 0)
//prints:
// bar init
// foo init
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Why does the following code compile?
Why does Bar's init(x: Int) automatically call Foo's init()?
Why don't I have to manually call super.init() myself?

This is intentional behavior. It kicks in when your super class has a single designated initializer with a zero-argument init. This is why you don’t have to call super.init() when deriving from NSObject.

-Chris

···

On May 16, 2016, at 7:09 AM, tuuranton--- via swift-users <swift-users@swift.org> wrote:

What passage of
The Swift Programming Language: Redirect
tells me that this should be the case?

--------------------
class Foo {
    init() {
        print("foo init")
    }
}
class Bar: Foo {
    init(x: Int) {
        print("bar init")
    }
}
let b = Bar(x: 0)
//prints:
// bar init
// foo init
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

I did not know of this behavior, but it looks like if the superclasses designated initializer is just a plain init() then it will automatically call super.init() from your subclass.

There is no way to avoid not calling your superclasses’s designated initializer and I guess the compiler ensures this by implicitly placing a call to super?

For example, if you change your Foo init to init(test:Int) { } then your subclass will complain that it’s not calling super’s designated initializer.

I have no idea why super can be implicitly called and I see no reference to this in the language guide.

I am not sure I like this behavior. It should either be documented (maybe I am missing it?) or requiring calling super explicitly.

Brandon

···

On May 16, 2016, at 10:09 AM, tuuranton--- via swift-users <swift-users@swift.org> wrote:

Why does the following code compile?
Why does Bar's init(x: Int) automatically call Foo's init()?
Why don't I have to manually call super.init() myself?

What passage of
The Swift Programming Language: Redirect
tells me that this should be the case?

--------------------
class Foo {
    init() {
        print("foo init")
    }
}
class Bar: Foo {
    init(x: Int) {
        print("bar init")
    }
}
let b = Bar(x: 0)
//prints:
// bar init
// foo init
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Why is this the intentional behavior? Seems a bit strange that init() is a
special exception to the rule.

16. May 2016 19:29 by clattner@apple.com:

···

On May 16, 2016, at 7:09 AM, tuuranton--- via swift-users <>> >> swift-users@swift.org>> > wrote:
          >> Why does the following code compile?>> Why does Bar's init(x:
Int) automatically call Foo's init()?>> Why don't I have to manually call
super.init() myself?

This is intentional behavior. It kicks in when your super class has a
single designated initializer with a zero-argument init. This is why you
don’t have to call super.init() when deriving from NSObject.
-Chris

What passage of>>
The Swift Programming Language: Redirect;
tells me that this should be the case?
-------------------->> class Foo {>> init() {>> print("foo
init")>> }>> }>> class Bar: Foo {>> init(x: Int) {>>
print("bar init")>> }>> }>> let b = Bar(x: 0)>> //prints:>> // bar
>> // foo init>> >>
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

Not a big fan of this implict behaviour. Not super obvious.

···

*___________________________________*

*James⎥Head of Trolls*

*james@supmenow.com <james@supmenow.com>⎥supmenow.com <http://supmenow.com>*

*Sup*

*Runway East *

*10 Finsbury Square*

*London*

* EC2A 1AF *

On 17 May 2016 at 10:48, tuuranton--- via swift-users <swift-users@swift.org > wrote:

Why is this the intentional behavior? Seems a bit strange that init() is a
special exception to the rule.

16. May 2016 19:29 by clattner@apple.com:

On May 16, 2016, at 7:09 AM, tuuranton--- via swift-users < > swift-users@swift.org> wrote:

Why does the following code compile?
Why does Bar's init(x: Int) automatically call Foo's init()?
Why don't I have to manually call super.init() myself?

This is intentional behavior. It kicks in when your super class has a
single designated initializer with a zero-argument init. This is why you
don’t have to call super.init() when deriving from NSObject.

-Chris

What passage of

The Swift Programming Language: Redirect
tells me that this should be the case?

--------------------
class Foo {
    init() {
        print("foo init")
    }
}
class Bar: Foo {
    init(x: Int) {
        print("bar init")
    }
}
let b = Bar(x: 0)
//prints:
// bar init
// foo init
_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

1 Like

Two reasons:

1) No one wants to call super.init() when deriving from NSObject.
2) More generally, if there is exactly one DI in your superclass, and if it takes zero arguments, it is usually not interesting to have to call it, it is just boilerplate.

If you think that this is the wrong policy, please bring it up on swift-evolution. Note that this has been the behavior since Swift 1, and I haven’t heard any other serious complaints about it.

-Chris

···

On May 17, 2016, at 2:48 AM, tuuranton@tutanota.de wrote:

Why is this the intentional behavior? Seems a bit strange that init() is a special exception to the rule.

I think it's the wrong policy because of this error:

'self' used before 'super.init' call

In this code:

    init(locationManager: CLLocationManager = CLLocationManager()) {
        self.locationManager = locationManager
        locationManager.delegate = self
    }

For a beginner who does not know about the automatic super.init() this error makes no sense because the call mentioned does not exist. If they had learned about requiring a super.init() in NSObject subclasses then they would know the obvious fix is to simply move the self usage below it.

     init(locationManager: CLLocationManager = CLLocationManager()) {
        self.locationManager = locationManager
        super.init()
        locationManager.delegate = self
    }

IMO these auto-behaviours make learning the language more difficult than necessary.

1 Like