swift継承とコンストラクタ

6310 ワード

継承

class Vehicle {

    var numberOfWheels: Int

    var maxPassengers: Int

    func description() -> String {

        return "\(numberOfWheels) wheels; up to \(maxPassengers) passengers"

    }

    init() {

        numberOfWheels = 0

        maxPassengers = 1

    }

}



class Bicycle: Vehicle {

    init() {

        super.init()

        numberOfWheels = 2

    }

}


書き換える


プロパティを書き換える場合は、定義を書き換える前にoverrideキーを付ける必要があります.これにより、同じ定義を誤って提供するのではなく、書き換えバージョンを提供したいことを示します.メソッド、プロパティ、または下付きスクリプトをfinalとしてマークすることで、キーワードを宣言する前に@finalプロパティを付けるだけで書き換えを防止できます.(例:@final var,@final func,@final class func,@final subscript)キーワードclassの前に@finalプロパティ(@final class)を追加することでクラス全体をfinalとマークすることができます.このようなクラスは継承できません.そうしないと、コンパイルエラーが報告されます.
  class Car: Vehicle {

    var speed: Double = 0.0

    init() {

        super.init()

        maxPassengers = 5

        numberOfWheels = 4

    }

    override func description() -> String {

        return super.description() + "; "

            + "traveling at \(speed) mph"

    }



    override var speed: Double  {

    get {

        return super.speed

    }

    set {

        super.speed = min(newValue, 40.0)

    }

    }





     override var speed: Double {

    didSet {

        gear = Int(speed / 10.0) + 1

    }

    }

}


ストレージ属性の初期付与


クラスと構造体は、インスタンスの作成時に、すべてのストレージ属性に適切な初期値を設定する必要があります.ストレージ属性の値は不明な状態にすることはできません.ストレージ・プロパティのデフォルト値を設定するか、コンストラクタに値を割り当てると、プロパティ・オブザーバ(property observers)はトリガーされません.

デフォルト属性値初期化属性


デフォルト値は、属性の初期化と属性の宣言をより緊密に結合します.デフォルト値を使用すると、コンストラクタがより簡潔で明確になり、デフォルト値から属性のタイプを自動的にエクスポートできます.
  struct Fahrenheit {

    var temperature = 32.0

}


コンストラクタ初期化プロパティ


コンストラクタは、特定のタイプの新しいインスタンスを作成するときに呼び出されます.キーワードinitで名前を付けます.
struct Fahrenheit {

    var temperature: Double

    init() {

        temperature = 32.0

    }

}


コンストラクタには、関数やメソッドのようにカッコの前に識別可能な名前がありません.したがって、コンストラクタを呼び出すときは、主にコンストラクタのパラメータ名とタイプによって呼び出すコンストラクタを決定します.パラメータが重要であるため、コンストラクタを定義するときにパラメータの外部名を指定しない場合、Swiftは各コンストラクタのパラメータに内部名と同じ外部名を自動的に生成し、各コンストラクタの前にハッシュ記号を付けることに相当します.
  struct Celsius {

    var temperatureInCelsius: Double = 0.0

    init(fromFahrenheit fahrenheit: Double) {

        temperatureInCelsius = (fahrenheit - 32.0) / 1.8

    }

    init(fromKelvin kelvin: Double) {

        temperatureInCelsius = kelvin - 273.15

    }

}


コンストラクションプロセスが終了する前に定数の値が決定される限り、コンストラクションプロセスの任意の時点で定数属性の値を変更できます.クラスインスタンスの定数属性は、クラスを定義する構築中にのみ変更できます.サブクラスでは変更できません.
class SurveyQuestion {

    let text: String = "sss";

    var response: String?

    init(_ text: String) {

        self.text = text

    }

    func ask() {

        println(text)

    }

}

var a  = SurveyQuestion("dddd")

a.ask();


デフォルトコンストラクタ


Swiftは、すべてのプロパティにデフォルト値が設定され、コンストラクタ自体が定義されていない構造体またはベースクラスにデフォルトのコンストラクタを提供します.
  class ShoppingListItem {

    var name: String?

    var quantity = 1

    var purchased = false

}

var item = ShoppingListItem()


個々のメンバーコンストラクタ---構造体のみ..クラスにはコンストラクタがありません


構造体がすべてのストレージ属性にデフォルト値を提供し、独自にカスタムコンストラクタを提供していない場合、各メンバーコンストラクタを自動的に取得できます.
struct Size {

    var width = 0.0, height = 0.0

}

let twoByTwo = Size(width: 2.0, height: 2.0)


値タイプにカスタムコンストラクタを定義すると、デフォルトのコンストラクタにアクセスできません(構造体の場合、オブジェクトコンストラクタは1つずつアクセスできません).この制限は、値タイプをより複雑に定義し、重要なコンストラクタの準備が完了した後も、自動的に生成されたコンストラクタを誤って使用することを防止します.

コンストラクタエージェント


コンストラクタは、他のコンストラクタを呼び出すことによって、インスタンスの一部のコンストラクタプロセスを完了することができる.このプロセスをコンストラクタエージェントと呼び、複数のコンストラクタ間のコード重複を減らすことができます.ネストコンストラクタメソッドは値タイプに対してselfを使用することができます.Initは、カスタムコンストラクタで同じ値タイプに属する他のコンストラクタを参照します.コンストラクタの内部でselfを呼び出すしかありませんinit.
struct Rect {

    var origin = Point()

    var size = Size()

    init() {}

    init(origin: Point, size: Size) {

        self.origin = origin

        self.size = size

    }

    init(center: Point, size: Size) {

        let originX = center.x - (size.width / 2)

        let originY = center.y - (size.height / 2)

        self.init(origin: Point(x: originX, y: originY), size: size)

    }

}


コンストラクタとコンビニエンスコンストラクタの指定

  • コンストラクタが直接親の指定コンストラクタを呼び出す必要があることを指定します.
  • 便利コンストラクタは、同じクラスで定義された他のコンストラクタを呼び出す必要があります.
  • 便利コンストラクタは、最終的に指定されたコンストラクタを呼び出して終了する必要があります.

  • コンビニエンスストアでは、initキーの前にconveninceキーを配置し、スペースを使用して2つを分離する必要があります.
      class Food {
    
        var name: String
    
        init(name: String) {
    
            self.name = name
    
        }
    
        convenience init() {
    
            self.init(name: "[Unnamed]")
    
        }
    
    }
    
    
    
    

    メソッド、プロパティ、および下付きとは異なり、コンストラクタを再ロードするときにキーワードoverrideを使用する必要はありません.
    リロードされたコンストラクタが指定されたコンストラクタである場合、サブクラスでインプリメンテーションをリロードし、カスタムバージョンのコンストラクタで親バージョンのコンストラクタを呼び出すことができます.リロードされたコンストラクタが便利なコンストラクタである場合、リロードプロセスは、同じクラスで提供されている他の指定されたコンストラクタを呼び出すことによって実現する必要があります.

    自動コンストラクタの継承

  • 子クラスに指定されたコンストラクタが定義されていない場合、すべての親クラスの指定されたコンストラクタが自動的に継承されます.
  • 子クラスがすべての親指定コンストラクタのインプリメンテーションを提供している場合、ルール1で継承されているか、カスタムで実装されているかにかかわらず、すべての親の便利なコンストラクタが自動的に継承されます.

  • 閉パッケージと関数による属性のデフォルト値の設定


    このタイプの閉パッケージまたは関数は、通常、属性タイプと同じ一時変数を作成し、その値を変更して予想される初期状態を満たし、最後にこの一時変数の値を属性のデフォルト値として返します.注意閉包の最後の括弧の後ろには空の括弧が付いています.これは、Swiftがすぐにこの閉パッケージを実行する必要があることを示すために使用されます.このカッコを無視すると、閉パケットの戻り値を属性に割り当てるのではなく、閉パケット自体を値として属性に割り当てることになります.プロパティの値を初期化するために閉パッケージを使用する場合は、閉パッケージの実行時にインスタンスの他の部分が初期化されていないことを覚えておいてください.これは、デフォルト値があっても、閉パッケージで他のプロパティにアクセスできないことを意味します.同様に、暗黙的なselfプロパティを使用したり、他のインスタンスメソッドを呼び出したりすることはできません.新しいインスタンスが作成されるたびに、対応する付与クローズが実行されます.
    struct Checkerboard {
    
        let boardColors: Bool[] = {
    
            var temporaryBoard = Bool[]()
    
            var isBlack = false
    
            for i in 1...10 {
    
                for j in 1...10 {
    
                    temporaryBoard.append(isBlack)
    
                    isBlack = !isBlack
    
                }
    
                isBlack = !isBlack
    
            }
    
            return temporaryBoard
    
            }()
    
        func squareIsBlackAtRow(row: Int, column: Int) -> Bool {
    
            return boardColors[(row * 10) + column]
    
        }
    
    }