2017-10-16 6 views
1

特定のクラスに属するオブジェクトを保持する配列を作成するにはどうすればよいですか?これを指定する方法はありますvar array : [BaseObject.Type] = []Swift - 特定のクラスタイプの配列

-

class BaseObject {} 

class Derived1: BaseObject {} 
class Derived2: BaseObject {} 
class Derived2: BaseObject {} 

は私がしただけのようなBaseObject

何かから派生したオブジェクト保持する配列を作成する必要がありますか?

また、私はあなたが明らかにBaseObjectの配列としてあなたの配列を定義することができ、この

if let derived1 = object as? [Derived1] { 

} 
else if let derived2 = object as? [Derived2] { 

} 
+2

'var array = [BaseObject]()' – Paulw11

+0

特定のクラスオブジェクトを使用するように配列を制限したいと思います。私は基本クラスを持つ配列を作成する場合。それから私は、任意の派生クラスを追加することができます、私はむしろ1つの派生型を作成したインスタンスに基づいて使用するように制限したい。 – nanjunda

+0

もし、* 1つの派生型のみを使用するように制限したいのであれば - 質問の情報と矛盾する - var array = [Derived1]() 'を使用してください – vadian

答えて

1

のようなもの、それを使用することができるはずです。

var objects: [BaseObject] = [] // or `var objects = [BaseObject]()` 

しかし、あなたが作成できるようになるだろう異種コレクション(BaseObjectまたはDerived1またはDerived2または他のサブクラスのいずれか)を含む。これは、BaseObjectのサブクラスが許可されるべきであり(そして許される)、OOの中心的な設計コンセプト(Liskov substitution principle)です。

あなたが望むすべてはあなたが唯一のサブタイプのいずれかの配列を持つことができるということであるならば、あなたは明らかにちょうど例えば、のようなあなたの配列を定義することができますが:

var objects: [Derived1] = [] 

明らかにのみDerived1オブジェクトを許可します(とDerived1の任意のサブクラス。


90%の時間、上記で十分である。しかし、「いくつかのケースでは、あなたは、いくつかの継承された基本動作を必要とする方法でいくつかのコレクションを必要とするかもしれませんが、そのためにあなたはドン許可したくない異種コレクションこの場合、私はより多くのプロトコル指向のパターンを検討してください:ボトムライン

  1. を、私たちは、サブクラス化しなければならない、あるいは我々は、プロトコル指向のアプローチを使用してすべきですか?私。実際には、独自の目的のためにインスタンス化するもの、またはサブクラスの共通の動作を定義するだけのものです。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メソッドを記述すると、Object1Object2などのように、このプロトコルに準拠するすべてのタイプがfooを実装せずに使用できます(ただし、何らかの理由で)。

  2. これはサブクラス化を排除するため、メンバーの均質性を規定しながら一般化された振る舞いを指示するジェネリックスとプロトコルの使用を開始します。例:

    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年のビデオ。

最後に、他にご質問がありましたら、このパターンで解決しようとしている実用的な問題の詳細をご記入ください。要約の議論はしばしば実り多いものではない。しかし、実際の問題があなたの質問のパターンで解決しようとしていることを教えてくれれば、はるかに建設的な会話になるでしょう。

+0

これは私が探していたものです。ありがとう@ロブ – nanjunda