2011-05-09 20 views
0

言語特有です(ただし、言語が必要な場合はC++/C#またはJavascriptを使用してください)。私はこれをどうやってやっていくのか、親オブジェクトからどのように子オブジェクトにアクセスするのかを考えようとしています。オブジェクト指向プログラミングN番目の子

は...私は、次のクラスがあり、これらは等を適切に記述されていないと言う。

クラス:roomContainer(オブジェクトのコンテナ)
クラス:テーブルのTable(基底クラス、最大の財産が含まれています-seats、座席の電流数の-シート、アレイ)
クラス:Desk(表を拡張し、最大値は、描画のアレイを描画するためのプロパティを含む)
クラス:席seat(基底クラス、maximum-のプロパティを含みます足、肘掛け、背もたれ)
クラス:couch(座席を拡張し、最大の座席を追加)

roomContainerのインスタンスを作成し、その中にテーブル、ソファを追加します。テーブルの中で私は複数の座席(または椅子)と机を作ります。

親オブジェクトに異なるオブジェクトのコンテナがある場合、子オブジェクトプロパティのプロパティにどのようにアクセスできますか。私はroomContainerオブジェクトのコンテナ、そのうちの1つはテーブル、そして机は異なるプロパティと描画配列などを持っています。

答えて

0

すべてが共通のメソッド(たとえば、Render(), Update(), SaveDetails(int Id), LoadDetails(int Id))であれば、すべてが基本クラスから継承されるようにすることもできますし、共通のインターフェイスを使用することもできます。これにより、共通のメソッドを呼び出すとき(または共通のプロパティにアクセスするとき)、キャスティング(以下)の必要性がなくなります。 派生クラスに固有のプロパティにアクセスするには、子オブジェクトのタイプをチェックし、子オブジェクトをキャストしてプロパティにアクセスします。

EDIT:例:

foreach(Object obj in Room.ChildObjects) 
{ 
    if(obj is Desk) 
    { 
     Desk DeskObj = obj as Desk; // Cast the object reference as a desk. 
     DeskObj.MaxDraws = 50; // It's a big desk! 
     DestObj.Draws[1] = new Draw(); // ...... 
    } 
} 
+0

彼らはさまざまな種類のオブジェクトであり、常にメソッドを共有していない場合(の場合、彼らは、同じメソッドに異なるタイプの入力がある場合)、オブジェクトを取得し、そのオブジェクトをコンテナから操作する必要があります。たとえば、私がルームコンテナ>デスクオブジェクト>描画に移動する必要がある描画のプロパティを設定する必要がある場合、配列から適切な描画オブジェクトを見つけてオブジェクトを返すメソッドがあります。その後、オブジェクトが返されたら、そのプロパティ/メソッドを呼び出しますか? – banvan

+0

@banvan、上記の私の編集を参照してください。 –

1

あなたはComposite Design Patternと呼ばれるものを探しています。これにより、(あなたが記述したように)オブジェクトをネストし、親と子の両方への参照を保持することができます(ただし、実装によっては親参照を保持しません。ここで

は、スキーマを使用した実装例である。このような

public static class Program  // the supporting class definitions are below 
{ 
    public static void Main() 
    { 
     // create a root container 
     var room = new RoomContainer(); 

     // create a child 
     var table = new Table(room, 4); 

     // put the table in the room 
     room.Add(table); 

     MakeMess(room); 
    } 

    // to show you how to access the properties 
    // if you don't already have a reference: 
    public static void MakeMess(RoomContainer room) 
    { 
     if(room == null) 
     { 
      throw new ArgumentNullException("room"); 
     } 
     var seats = room.GetChildren<Table>().First().Seats.ToArray(); 
     for (int index = 0; index < seats.Length; index++) 
     { 
      Console.WriteLine("You have kicked over Seat #{0}",(index+1).ToString()); 
     } 
    } 

} 

// This is the base class of the components and provides the core functionality. 
// You will want to make this object's interface minimal, so that the logic 
// is consistent with all its children (without knowing what they might be in advance) 

public abstract class Component 
{ 

    private readonly IList<Component> _children; 
    private readonly Component _container; 

    protected Component(Component container) 
    { 
     _container = container; 
     _children = new Component[] { }; 
    } 

    public bool IsRoot { get { return _container == null; } } 

    public abstract bool IsContainer { get; } 


    public virtual void Add(Component component) 
    { 
     if (component == null) 
     { 
      throw new ArgumentNullException("component"); 
     } 
     if (!IsContainer) 
     { 
      throw new NotSupportedException("Add is not supported by leaf components"); 
     } 
     _children.Add(component); 
    } 

    public IEnumerable<T> GetChildren<T>() 
     where T: Component 
    { 
     if (!IsContainer) 
     { 
      throw new NotSupportedException("Only containers have children"); 
     } 
     return _children.OfType<T>(); 
    } 

    public IEnumerable<Component> Children 
    { 
     get 
     { 
      if (!IsContainer) 
      { 
       throw new NotSupportedException("Only containers have children"); 
      } 
      return _children; 
     } 
    } 

} 

public class RoomContainer : Component 
{ 
    public RoomContainer() : base(null) 
    { 
    } 

    public override bool IsContainer { get { return true; } } 
} 

public class Table : Component 
{ 
    private readonly int _maximumSeatCount; 

    public Table(Component container, int maximumSeatCount) : base(container) 
    { 
     _maximumSeatCount = maximumSeatCount; 
    } 

    public override bool IsContainer { get { return true; } } 


    protected virtual bool CanAdd(Component component) 
    { 
     return component is Seat && MaximumSeatCount > CurrentSeatCount; 
    } 

    public override void Add(Component component){ 
      if(CanAdd(component)){ 
       base.Add(component); 
      } 
      else 
      { 
       throw new NotSupportedException("The component was an invalid child of Table and could not be added."); 
      } 
     } 

    public int MaximumSeatCount { get { return _maximumSeatCount; } } 
    public int CurrentSeatCount { get { return Seats.Count(); } } 
    public IEnumerable<Seat> Seats { get { return Children.OfType<Seat>(); } } 
} 
public class Seat : Component 
{ 
    // you can restrict the constructor to only accept a valid parent 
    public Seat(Table table) : base(table) 
    { 
    } 

    public override bool IsContainer 
    { 
     get { return false; } 
    } 
} 
0

は何か:

IEnumerable<Desk> desks = roomContainer.OfType<Desk>(); 
//Iterate and do stuff. 
IEnumerable<Table> tables = roomContainer.OfType<Table>(); 
//Iterate and do stuff. 
+0

これは 'RoomContainer'がIEnumerableを実装している場合にのみ意味があります – smartcaveman

関連する問題