The construction rule in inheritance is a difficult point. If there is a problem, please leave a message to ask me.
My Swift Introductory Tutorial column
Why have constructors: Assign an initial value to the stored properties of the class itself and the inheritance.
One, two constructors-specifying constructors and convenience constructors
Specifies the constructor: a prerequisite constructor in the class that assigns an initial value to all properties. (some subclasses may not need to display the declaration because the default inherits from the base class)
Convenience constructor: A secondary constructor in a class that assigns an initial value to a property by invoking the specified constructor. (declared only when necessary)
Example
Class Food { var name:string init (name:string) { self.name = name } convenience init () { Self.init (Name: "[Unnamed]") }}
The convenience constructor is declared by the convenience keyword, and you can see that the convenience constructor is constructed by invoking the specified constructor. This is also a key concept: horizontal proxies.
What is an agent: let others help you work
II. rules in the construction process
(a) The constructor chain is the order in which the constructor is called
The rules are as follows:
1.1. Specifies that the constructor must call the specified constructor of its parent class
1.2. The convenience constructor must call the specified constructor in the same class
1.3. The convenience constructor must end with the invocation of a specified constructor
Always say a word: Convenient constructor horizontal proxy, specify constructor upward proxy.
As an example:
Class base{ var basevar:string init (baseinput:string) { Basevar = baseinput } convenience init () { Self.init (baseinput: "") }}class sub:base{ var subvar:string; Init (subinput:string,baseinput:string) { Subvar = subinput super.init (baseinput:baseinput)//Here is Rule 1.1 } Convenience init (consubinput:string) { self.init (subinput:consubinput,baseinput: "")//Here is the rule 1.2 } Convenience init () { self.init (consubinput: "")//This is rule 1.3 because another convenience constructor is called, and the other facilitates the constructor to invoke the specified constructor end }}
(ii) inheritance and overloading of constructors
In swift, subclasses do not inherit the constructor of the parent class by default.
Constructors ' overloads follow the rules of the constructor chain (1.1-1.3)
The constructor inherits the following rules:
2.1. If no specified constructors are defined in the subclass, the specified constructors for all parent classes are automatically inherited
2.2. If all the parent classes in the subclass are provided with the specified constructor, whether inherited by rule 2.1 or custom implementation, it inherits the convenience constructor of all the parent classes.
Attention:Subclasses can implement the specified constructor of a parent class by partially satisfying rule 2.2 by using a subclass convenience constructor。
Example one:
Class base{ var basevar:string init (baseinput:string) { Basevar = baseinput } convenience init () { Self.init (baseinput: "Basevar") }}class sub:base{ var subvar:string = "Subvar";}
Here the subclass does not define any constructors, so rule 2.1, 2.1, will inherit the specified constructors and convenience constructors of all the parent classes
So you can call this
var Instance1 = sub () var Instance2 = sub (baseinput: "Newbasevar")
Example Two
Class base{ var basevar:string init (baseinput:string) { Basevar = baseinput } init (firstpart: string,secondpart:string) { Basevar = Firstpart + secondpart } convenience init () { self.init ( Baseinput: "Basevar") }}class sub:base{ var subvar:string; Init (subinput:string,baseinput:string) { Subvar = subinput super.init (baseinput) }}
Here, the subclass simply implements a constructor for the parent class, so it does not inherit the convenience constructor, nor does it inherit another specified constructor
You can only create instances like this.
var instance = Sub (subinput: "Subvar", Baseinput: "Basevar")
(iii) based on the above two rules, the construction process is divided into two parts
Stage One
- A specified constructor or a convenience constructor is called;
- Complete the memory allocation for the new instance (memory has not been initialized at this time);
- Specifies that the constructor ensures that all the storage properties it introduces have been assigned (the storage attribute is extremely memory-initialized);
- Specifies that the constructor calls the parent class constructor (parent class constructor property initialization);
- The constructor that calls the parent class goes up the chain of constructors up to the top. (Ensure that all inherited base class procedures have been initialized.)
Phase II
- From the top down, the constructor specified by the class in each constructor chain has the opportunity to further customize the instance, at which time the constructor can access self, modify its properties, invoke instance methods, and so on.
- Finally, the convenience constructor of any constructor will have the opportunity to customize the instance and use self.
Maybe this rule is a little abstract, for example.
Class base{ var basevar:string init (baseinput:string) { Basevar = baseinput }}class sub:base{ var subvar:string; Func Subprint () { println ("Can now Invoke instance method") } init (subinput:string,baseinput:string) { Subvar = Subinput super.init (baseinput:baseinput)//This completes the stage one Self.subvar = subinput + "123"//You can call self at this time Subprint ()//The instance method can also be invoked at this time }}
Always: When the memory of the instance of the class is initialized, that is, after calling Super.init (), the phase one is completed.
Third, the compiler security check
Check a
Specifies that the constructor must be initialized before the properties of the class it resides on to delegate the construction task up to the constructor in the parent class. To put it simply, initialize your own storage property first, and initialize it in the super.init of the calling parent class.
Check Two
Specifies that the constructor must first call the parent class constructor, assigning an initial value to the inherited property. This very simple answer, assuming that the inheritance of X, you first to assign a value of 1, and in the call to the parent class constructor, the parent constructor will give X to assign another initial value to ensure that the initialization process is complete, then your assignment 1 is overwritten
Check Three
The convenience constructor calls the other constructors in the same class first, and then assigns the initial value to any attribute. Similar to check two and is also prevented from being overwritten
Check Four
The constructor cannot drink self until the first stage is complete, cannot invoke any instance properties, cannot invoke an instance method
Four, summarize
The procedure for specifying a constructor is this
1. Assigning an initial value to a property of its own
2. Call the base class constructor (Super.init)
3. You can then call self, and instance methods, to store properties. Customize the new value.
Then, let's look at a better example from the official documentation.
Class Food { var name:string init (name:string) { self.name = name } convenience init () { Self.init (Name: "[Unnamed]") }}class recipeingredient:food { var quantity:int init (name:string, Quantity:int) { self.quantity = quantity super.init (name:name) } override convenience init (name: String) { self.init (name:name, quantity:1) }}class shoppinglistitem:recipeingredient { var purchased = False var description:string { var output = "\ (quantity) x \ (name.lowercasestring)" { output + = purchase D? "YES": "NO" Return output }}
The relationship of this constructor chain
Explain
- Base class food defines a specified constructor and a convenience constructor
- Subclass Recipeingredient implements all the specified constructors of the base class food, so it inherits the convenience constructor of the base class
- Subclass Shoppinglistitem does not have a constructor defined, so it inherits all constructors of the base class Recipeingredient. Swift Introductory Series 15-construction rules in succession (difficulty)
Swift Difficulty-the construction rule instance in inheritance is detailed