のようなもの、それを使用することができるはずです。
var objects: [BaseObject] = [] // or `var objects = [BaseObject]()`
しかし、あなたが作成できるようになるだろう異種コレクション(BaseObject
またはDerived1
またはDerived2
または他のサブクラスのいずれか)を含む。これは、BaseObject
のサブクラスが許可されるべきであり(そして許される)、OOの中心的な設計コンセプト(Liskov substitution principle)です。
あなたが望むすべてはあなたが唯一のサブタイプのいずれかの配列を持つことができるということであるならば、あなたは明らかにちょうど例えば、のようなあなたの配列を定義することができますが:
var objects: [Derived1] = []
明らかにのみDerived1
オブジェクトを許可します(とDerived1
の任意のサブクラス。
90%の時間、上記で十分である。しかし、「いくつかのケースでは、あなたは、いくつかの継承された基本動作を必要とする方法でいくつかのコレクションを必要とするかもしれませんが、そのためにあなたはドン許可したくない異種コレクションこの場合、私はより多くのプロトコル指向のパターンを検討してください:ボトムライン
を、私たちは、サブクラス化しなければならない、あるいは我々は、プロトコル指向のアプローチを使用してすべきですか?私。実際には、独自の目的のためにインスタンス化するもの、またはサブクラスの共通の動作を定義するだけのものです。BaseObject
後者の場合、プロトコルは、より良いパターン、例えば:
protocol Fooable {
func foo()
}
// if you want, provide some default implementation for `foo` in an
// protocol extension
extension Fooable {
func foo() {
// does something unique to objects that conform to this protocol
}
}
struct Object1: Fooable {}
struct Object2: Fooable {}
struct Object3: Fooable {}
これはあなたのより多くのオブジェクト指向のアプローチに使用してますが、プロトコルを使用しているかもしれ行動のようなものを生み出すかもしれません。具体的には、foo
メソッドを記述すると、Object1
、Object2
などのように、このプロトコルに準拠するすべてのタイプがfoo
を実装せずに使用できます(ただし、何らかの理由で)。
これはサブクラス化を排除するため、メンバーの均質性を規定しながら一般化された振る舞いを指示するジェネリックスとプロトコルの使用を開始します。例:
struct FooCollection<T: Fooable> {
private var array = [T]()
mutating func append(_ object: T) {
array.append(object)
}
// and let's assume you need some method for your collection that
// performs some `Fooable` task for each instance
func fooAll() {
array.forEach { $0.foo() }
}
}
これは、プロトコルに準拠したオブジェクトの同種の集合であるジェネリックです。たとえば、あなたがそれを使用するために行くとき、あなたが使用するFooable
タイプの特定の型を宣言したい:他の場所でのコメントで、あなたが問い合わせるれたため、今
var foo = FooCollection<Object1>()
foo.append(Object1()) // permitted
foo.append(Object2()) // not permitted
foo.fooAll()
、私はこの道を下って行きジェネリック医薬品。私は個人的には、(a)コレクションが本当に均質である必要がある場合にのみ、この道を下って行きます。 (b)コレクションはまた、プロトコルに共通の共有ロジックを実装したいと考えました。それ以外の場合は、単純な[Derived1]
(または[Object1]
)と貼り付けるだけです。上記は必要に応じて強力になる可能性がありますが、よりシンプルな状況では過剰です。あなたは伝統的なオブジェクト指向の考え方から来ているとき、私はあなたがWWDC 2015ビデオ、Protocol-Oriented Programming in Swiftを参照してくださいしたいプロトコル指向プログラミング、異質な行動対均質な、伝統的なつまずきブロックの詳細な議論については
、またはそれが構築すること2016 companion videoです2015年のビデオ。
最後に、他にご質問がありましたら、このパターンで解決しようとしている実用的な問題の詳細をご記入ください。要約の議論はしばしば実り多いものではない。しかし、実際の問題があなたの質問のパターンで解決しようとしていることを教えてくれれば、はるかに建設的な会話になるでしょう。
出典
2017-10-16 07:56:59
Rob
'var array = [BaseObject]()' – Paulw11
特定のクラスオブジェクトを使用するように配列を制限したいと思います。私は基本クラスを持つ配列を作成する場合。それから私は、任意の派生クラスを追加することができます、私はむしろ1つの派生型を作成したインスタンスに基づいて使用するように制限したい。 – nanjunda
もし、* 1つの派生型のみを使用するように制限したいのであれば - 質問の情報と矛盾する - var array = [Derived1]() 'を使用してください – vadian