2016-07-24 6 views
1

強く型付けされた実装では悪い習慣ですが、サブクラスで変更する必要のある汎用コードがあります。 obj-cコードのgetterとsetterは、id型付きの値を扱うので、より一般化された値が必要です。最初にObj-cのスーパークラスで定義されたswiftクラスのプロパティをオーバーライド

// objc 
@interface A 
@property NSNumber* foo; 
@end 

// swift subclass 
class B : A { 
    var foo: String? 
} 

プロパティを定義するにはスクロールがあるので、それは完全にスーパークラスプロパティに置き換えられますか?

(id)タイプのObj-cの緩やかな型付けの性質により、柔軟性が確保され、迅速に閉じられます。

答えて

2

これはできません。プロパティをオーバーライドして異なる動作を提供できますが、タイプを変更するとオブジェクト指向設計に違反し、コンパイルされません。

override var foo: NSNumber! { 
    get { return NSNumber(int: 5) } 
    set { } 
} 

編集:なぜ、このブレークOOを行い

は、プロパティをオーバーライドするには?

理由Aから継承することで、あなたはこのような機能を持っていた場合に何が起こるか想像A.のように行動することを約束していることである:

あなたが提出しようとした場合に何が起こるか
func doStuff(obj: A) { 
    print("Foo/2: \(Float(obj.foo.integerValue)/2.0)") 
} 

Bのインスタンスはここですか?強く型付けされコンパイルされた言語では、これは調整できません。動的言語では、実行時エラーが発生します。

私もLiskov Substitution Principle言及します:

の代入はSがTのサブタイプである場合は、コンピュータプログラムで、その後、型Tのオブジェクトはかもしれ、と述べているオブジェクト指向プログラミングにおける原則でありますそのプログラムの望ましい特性(正しさ、実行されたタスクなど)を変更することなく、タイプSのオブジェクトに置き換えられる(すなわち、タイプTのオブジェクトは、タイプSのサブタイプオブジェクトで置き換えられることができる)。

これは、メソッドの既存の動作を破棄してはならないと指摘しています。あなたのスーパークラスで動作するプロシージャは、サブクラス化されているからです。しかし、同じことが構造にも当てはまります。ガイドラインではなく、コンパイラがこれを強制するだけです。

+0

おかげで、ちょうどクエリ、それはオブジェクト指向設計を破るか?プロパティをオーバーライドする機能として、チェーンの継承を破ることは、依然として適合しているようです。 b.fooとのやり取りは文字列になり、a.fooは数字になります。クラスは依然として強く型付けされており、その点で型安全です。 –

+0

(私の答えにコメントを移動しました) –

+0

すごく、ありがとう、投稿してください。私はこれまでずっとこれを勉強していたことを覚えていますが、エクステンションのようなオブジェクト構造の他のスタイルとは常に違和感がありました。とにかく、あなたは私の質問に感謝しました。これはイデオロギープログラミングのテクニックに傾倒しています。 –

関連する問題