The construction rule in inheritance is a difficult point.
If there is a problem, please leave a message to ask me.
My Swift beginner's tutorial column
Http://blog.csdn.net/column/details/swfitexperience.html
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. Assigns an initial value to all attributes. (some subclasses may not need to display the declaration, because it inherits from the base class by default)
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 can be seen through the Conveniencekeyword declaration. 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
Rules such as the following:
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.
To give a sample 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: "")//Here is Rule 1.3, because another convenience constructor is called, and another convenience constructor ends with a call to the specified constructor }}
(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 inheritance rules for constructors are as follows:
2.1. Assuming that the subclass is undefined, no matter what the constructor is specified, it will voluntarily inherit the specified constructors of all the parent classes.
2.2. Suppose that all the parent classes are provided in the subclass to specify the constructor, whether it is inherited through rule 2.1 or its own definition, 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";}
The subclass here does not define any constructors, so rule 2.1, 2.1, will inherit all of the parent class's specified constructors and convenience constructors
So I can call it that way
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
Just being able to 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 of the storage properties it introduces have been assigned (the storage property is extremely memory initialized).
- Specifies that the constructor calls the parent class constructor (parent class constructor property initialization).
- The constructor that invokes the parent class is up along the chain of the constructor. Until the top of the. (Ensure that all inherited base class procedures have been initialized.)
Phase II
- down from the top. The constructors specified in each constructor chain have the opportunity to further customize the instance. The constructor can now access self, change its properties, invoke instance methods, and so on.
- Finally, the handy constructor of the free constructor will have the opportunity to customize the instance and use self.
Maybe the rule is a little abstract. Give me a sample to make it clear
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)//Here it is. Stage One Self.subvar = subinput + "123"//Can call self at this time Subprint ()//can also invoke instance methods at this time }}
Always: When the memory of the instance of the class is initialized, that is, after calling Super.init (), the stage is complete.
third, the compiler security check
Check a
Specifies that the constructor must delegate the construction task up to the constructor in the parent class after the properties of its class are initialized. In simple terms. is to initialize its own storage property first, and initialize the super.init of the calling parent class.
Check Two
Specifies that the constructor must call the parent class constructor up first. Assigns an initial value to an inherited property.
This very simple answer, if you inherit an X, you first assign the value of X to 1, and then you call the parent class constructor. The parent constructor assigns an additional initial value to X to ensure that the initialization process is complete, and that 1 of your assignment is overwritten.
Check Three
The convenience constructor first calls the other constructors in the same class, and assigns the initial value to the random attribute. and check two similar. is also prevented from being overwritten
Check Four
The constructor is before the first phase is complete. Cannot consume self, cannot invoke no instance property, cannot invoke instance method
Four, summarize
The process of 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 good example given in 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 the specified constructor for the base class food. So it inherits the convenience constructor of the base class.
- Subclass Shoppinglistitem does not define a constructor, so it inherits all constructors of the base class Recipeingredient. Swift Introductory Series 15-construction rules in succession (difficulty)
Swift Difficulty-constructor rule instance in inheritance specific explanation