Swift Learning notes (vi)

Source: Internet
Author: User

12 subscript

1, under the slogan Law  

Subscript allows you to retrieve an element from the instance name by adding one or more values in parentheses. Syntax and method syntax are similar to property syntax by using the subscript key definition, one or more input parameters, and a return value. Unlike instance methods, subscripts can be read-write or read-only. This behavior is connected by a getter and setter statement, just like a computed property.

Subscript (index:int), Int {    get {        return an appropriate subscript value here    }    set (NewValue) { C17/>perform a suitable setting action here    }}

The type of newvalue is the same as the type returned by the subscript. As with computed properties, you can choose not to specify the parameters of the setter , because the default parameter, NewValue, is provided to the setter when you do not specify it .

As with computed properties, read-only subscripts do not require a get keyword

Here is an implementation of a read-only subscript that defines a timestable structure to represent the number of multiples of an integer:

In this example, the instance timestable is created as a 3- fold number, which is set by the value 3 passed in to the multiplier parameter at initialization time .

Attention:

The Times tables are set according to a specific mathematical rule, so a new value should not be set for the Threetimetable[someindex] element, so the subscript of the timestable is defined as read-only.

struct Timestable {let    multiplier:int    subscript (index:int), Int {        return multiplier * Index    } }let threetimestable = timestable (multiplier:3) print ("six times three is \ (Threetimestable[6])")

2, the use of subscript

The exact meaning of the subscript is determined by the context in which it is used. The subscript is used primarily as an element shortcut for collections, lists, and sequences. You are free to define the subscript you need for your class or structure.

For example, the subscript implemented by the dictionary type in Swift is to set and retrieve values from the dictionary instance. You can set multiple values by giving the keywords and values in the subscript separately, or you can set the value of a single dictionary by subscript:

var numberoflegs = ["Spider": 8, "Ant": 6, "cat": 4]numberoflegs["bird"] = 2

In the example above, a variable numberoflegs is defined andthen initialized by a key-value pair. The type of Numberoflegs is the dictionary type dictionary<string, int>. After the dictionary was created, the example uses the subscript assignment method to add a key of type string "Bird" and an Int value of 2 to the dictionary.

Attention:

The key-value pairs that are implemented by the dictionary type in Swift are optional types. For the numberoflges dictionary, the value returned is int, which isan optional int value. The dictionary uses an alternative type subscript to indicate that not all keys have corresponding values. You can also delete this key by assigning a value of nil to the key.

3. Subscript Options

Subscripts can receive any number of parameters, and the types of parameters can vary. The subscript can also return any type of value. subscripts can use variable arguments or variable parameters, but cannot use input or output parameters or provide values for default parameters.

Classes or structs can implement various subscripts as needed, and can use the appropriate subscript to return the desired value by using the parameters in the brackets when needed. The definition of this multi-subscript is called the subscript overload.

of course, the most common subscript usage is a single parameter, or you can define subscripts for multiple parameters. The following example shows a matrix matrixdouble

struct Matrix {let rows:int, columns:int var grid: [Double] Init (rows:i NT, columns:int) {self.rows = rows self.columns = Columns Grid = Array (count:rows * columns, Repea tedvalue:0.0)} func indexisvalidforrow (Row:int, column:int), Bool {return row >= 0 && ro  W < rows && column >= 0 && column < columns} subscript (Row:int, column:int), Double {get {assert (Indexisvalidforrow (row, Column:column), "Index Out of Range") return grid[(R ow * columns) + column]} set {assert (Indexisvalidforrow (row, Column:column), "Index out of the RAN GE ") grid[(Row * columns) + column] = newvalue}}} 

Matrices Matrix provides an initialization method that uses two parameters , rows and columns, andthen establishes an array to store values of type Double rows*columns . The positions in each matrix are set with an initial value of 0.0. This is done by passing the initial value 0.0 and array length to the arrays initialization method

You can pass two parameters row and column to complete the Matrix initialization:

var matrix = matrix (Rows:2, Columns:2)

The values in the matrix can be set by using subscripts that contain row and column and commas:

Matrix[0, 1] = 1.5matrix[1, 0] = 3.2

The Matrix subscript Both getter and setter methods include an assertion statement to check if the subscript row and column are valid. Use the indexisvalid method to determine whether row and column are within the range of the matrix:

If the access matrix is out of bounds, the assertion is triggered:

Let somevalue = matrix[2, 2]

Console print: Assertion failed:index out of Range:file <expr>, line 61

13 Inheritance

1 , define a base class

Any class that does not inherit from another class is called a base class.

Note: the Swift class is not inherited from a global base class. When you write code, classes that are not inherited from the parent class are the base classes as long as they are in the definition of the class.

The following example defines a base class called Vehicle. The base class contains the properties Numberofwheels and maxpassengers that are common to all two vehicles . These two properties are used by a method called description, which is characterized by the return of a String description of the vehicle:

Class Vehicle {    var numberofwheels:int    var maxpassengers:int    func description (), String {        Return "\ (numberofwheels) wheels; Up to \ (maxpassengers) passengers "    }    init () {        numberofwheels = 0        maxpassengers = 1    }}

The vehicle class Vehicle also defines a constructor to set its properties.

You can create an instance of a type by using a constructor function. Although constructors are not methods, they use very similar syntax when coding. The constructor creates a new instance by ensuring that the properties of all instances are valid.

Use the constructor syntax TypeName and empty two parentheses to complete the creation of a Vehicle instance:

Let somevehicle = Vehicle ()

the Vehicle constructor sets some initial values for the property (numberofwheels = 0 and then maxpassengers = 1).

The Vehicle class defines a generic transport feature that does not have much meaning in itself, so it is necessary to define some of its properties or methods to make it practical.

2. Generation of sub-categories

Generating a subclass is the process of generating a new class from an existing class. Subclasses inherit some of the attributes that can be modified by the parent class. You can also add some new attributes to the subclass.

To indicate that a class is inherited from a parent class, you need to write the name of the parent class after the subclass, separated by a colon

Define a new class called Bicycle, which inherits the attributes of Vehicle:

Class Bicycle:vehicle {    override init () {        super.init ()        numberofwheels = 2    }}

Not only is the property inherited from Vehicle , But Bicycle also inherits the method of the parent class. If you create an instance and then invoke the inherited description method, you can get a description of the vehicle and see that its properties have been modified:

Let bicycle = Bicycle () print ("Bicycle: \ (bicycle.description ())")

Note: Subclasses can only modify the properties of a variable at construction time, and cannot modify the properties of a constant.

3. Overriding method

Subclasses can provide instance methods inherited by the parent class, class methods, instance properties, or a personalized implementation of the subscript. This feature is called rewriting.

Overriding an inherited method requires that the Override keyword be annotated before the method definition . By doing this, you can ensure that the method you are modifying is actually inherited without a rewrite error. Incorrect rewriting can cause unpredictable errors, so if you do not mark the override keyword, it will be wrong in the code compile times.

The override keyword also allows the Swift compiler to check if the parent class of the class has a matching method to ensure that your rewrite is available and correct.

Accessing parent class methods, properties, and subscripts

When overriding subclasses inherit from a method, attribute, or subscript of a parent class, a subset of the existing implementations of the parent class are required. For example, you can redefine a known implementation or store a modified value in an inherited variable.

When appropriate, you can access the methods, attributes, or subscripts of the parent class by using the super prefix

Replication method

You can implement custom instance methods or class methods that inherit from the parent class in your subclass.

The following example shows a Vehicle subclass called Car , overriding the description method that inherits from Vehicle .

Class Car:vehicle {    var speed:double = 0.0    override init () {        super.init ()        maxpassengers = 5        nu Mberofwheels = 4    }    override func description ()-String {        return super.description () + ";"            + "Traveling at \ (speed) mph    }}"

a new Double type of storage property is defined in Car speed . The default value for this property is 0.0, which means 0 miles per hour. Car also has a custom constructor that sets the maximum number of passengers to 5, and the number of wheels is 4.

Car Overrides the inherited description method and labels the override keyword before the method name Description .

does not give a completely new description implementation in Description, or use the Partial description statement provided by Vehicle, and then add some of the attributes that you have defined, such as the current speed.

Let car = car () print ("Car: \ (car.description ())")

Replication properties

You can also provide personalization getter and setter methods that inherit instance properties from the parent class or class properties , or add property observers to implement overridden properties to observe the changes in inherited properties.

Overriding properties of Getters and Setters

Regardless of whether the attribute inherited in the source class is a stored or computed property, you can provide a custom getter or setter method to override this inheritance property. Subclasses generally do not know whether this inherited property is a property or a computed property, but it knows that the attribute has a specific name and type. You need to specify the type and name of the property when overriding, so that the compiler can check if your override matches the property of the parent class.

You can inherit a read-only property from Getter and setter to read-write, but not vice versa.

Note: If you provide a setter method for an overriding property , you also need to provide a getter method. If you do not want to modify the value of the inherited property in the Getter , you can use Super.someproperty in the getter , Speedlimitedcar below This is also true in the example.

The following example defines a new class Speedlimitedcar, which is a subclass of Car. This class represents a vehicle that is displayed in the code. Implemented by overriding the inherited speed property:

Class Speedlimitedcar:car {    override var speed:double  {        get {            return super.speed        }        set {            super.speed = min (newvalue, 40.0)}}    

overriding attribute observers

You can use property overrides to add an observer to an inherited property. This approach allows you to get a reminder of how this property will change, regardless of how it was implemented before.

Note: You cannot add observers for inherited constants or for read-only computed properties. These property values cannot be modified, so it is not appropriate to add willset or didset methods When overriding the implementation .

Note: You cannot define both the override setter and the overridden property observer, if you want to observe the change in the property value, and give the property a custom setter, it only needs to be in the setter You can get the change of the property value directly.

The following code shows a new class Automaticcar, which is also a subclass of Car. This class indicates that a car with an automatic gearbox can automatically select the gear according to the current speed and output the present gear in the description:

Class Automaticcar:car {    var gear = 1    override var speed:double {        Didset {            gear = Int (speed/10.0) + 1        }    }    override func description () String {        return super.description () + "in gear \" (gear) 
   
    }}
   

This can be achieved every time you set speed Value, thedidset method will be called to see if the gear needs to change. The gear is calculated from the speed divided by 1 , so the gear position is 4 when the Velocity is a plus:

Let Car1:automaticcar = Automaticcar () Car1.speed = 35car1.description ()

4 , prohibit rewriting

You can suppress the override of a class's methods, attributes, or subscripts by marking the final keyword. You can label the final attribute before the defined keyword .

Any attempt to override the final method of the parent class in the subclass , the behavior of the property or subscript will be wrong at compile times. The same method that is added to the class in the extension, the attribute or subscript can also be marked as final.

You can also use the final tag in front of the Class keyword class as final (final class ). Any subclass that attempts to inherit this parent class will be in the compile times error.

Swift Learning notes (vi)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.