web-dev-qa-db-ja.com

Swiftインスタンス変数のオーバーライド

この回答が他の形式ですでに投稿されていることは知っていますが、Swiftでインスタンス変数をオーバーライドする方法について詳しく知りたいと思います。

私はこのコードを持っているとしましょう

class BaseView:UIView{
 let someVariable:Int = 1
 // do some work with someVariable
}

class ExtendedView:BaseView{
 let someVariable:Int = 2
}

OK。私が読んだものから、定数はオーバーライドプレフィックスを必要とします。他の回答は、セッターとゲッターを宣言する必要があると言っていますか?どうして?私は本当にこれらの2つを気にしません。値を置き換えるだけです。 UIViewから継承しているため、initオーバーライドを実際に使用することはできません。これは非常に危険です(と思います)。

どんな提案も歓迎します。

30

あなたが言うように、サブクラスで定数を単純に再定義することはできません(結局は定数です)。表示されるエラーは、「保存されたプロパティでオーバーライドできません」です。 varをオーバーライドできるように見えますが、let someVariablevar someVariableに変更すると、サブクラスでアクセスすると「 'someVariable'の曖昧な使用」が発生します。 (注-overrideを使用してもしなくても同じことが起こります)。

最も簡単な解決策は、ゲッターを使用することです。これは実際には関数なので、喜んでオーバーライドできます。バッキング変数は管理されます。セッターを指定しない場合は、クラスごとに一定になります。

class BaseView: UIView {
    var someVariable: Int { get { return 1 } }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { get { return 2 } }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2

コメンテーター@ user3633673が指摘しているように、onlyにゲッター(セッターではなく)がある場合、getをドロップできますが、原則を明確にするために残しておきます。これなしでも同じです...

class BaseView: UIView {
    var someVariable: Int { return 1 }
    // do some work with someVariable
}

class ExtendedView: BaseView {
    override var someVariable: Int { return 2 }
}

let a = BaseView()
a.someVariable // 1
let b = ExtendedView()
b.someVariable // 2
61
Grimxn