2011-05-09 6 views
0

특정 언어 (그러나 언어가 필요한 경우 C++/C# 또는 Javascript를 사용하십시오). 이 작업을 수행하는 방법과 부모 개체에서 자식 개체에 액세스하는 방법을 알아 내려고했습니다. 객체 지향 프로그래밍 N 번째 하위 언어

내가 다음과 같은 클래스를 가지고 말해, 이들은 ... 제대로 등 작성되지 않은 :

클래스 : roomContainer (객체의 컨테이너)
는 클래스 : 테이블의 Table (기본 클래스, 최대의 속성이 포함 -seats 현재 번호 -의 좌석 시트의 배열)
분류 : 최대 무위한 Desk (표 연장, 추첨 배열) 속성을 포함
클래스 : seat (좌석 기본 클래스는 maximum-의 속성을 포함 다리, 팔걸이, 등받이)
클래스 : couch (좌석 확장, 재산 최대 좌석 추가)

roomContainer의 인스턴스를 만들고 그 컨테이너에 테이블, 소파를 추가합니다. 테이블 안에는 여러 개의 의자 (또는 의자)와 책상이 있습니다.

부모 개체가 다른 개체의 컨테이너를 가질 때 어떻게 자식 개체 속성의 속성에 액세스 할 수 있습니까? 예 : roomContainer 컨테이너의 컨테이너, 그 중 하나는 테이블, 그리고 책상 - 다른 속성과 무승부 배열 등이 있습니다.

답변

0

모두가 공통적 인 방법을 사용하는 경우 (예 : Render(), Update(), SaveDetails(int Id), LoadDetails(int Id)) 모두 기본 클래스에서 상속하거나 모든 인터페이스를 공용 인터페이스로 만들 수 있습니다. 이렇게하면 공통 메소드를 호출 할 때 (또는 공통 속성에 액세스 할 때) 캐스팅 (아래)의 필요성이 제거됩니다. 파생 클래스에 고유 한 속성에 액세스하려면 하위 개체의 유형을 확인한 다음 하위 개체를 캐스팅하여 속성에 액세스합니다.

편집 : 예 :

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

경우의 그들 동일한 메소드가 다른 유형의 입력을 가짐) 객체를 가져와 컨테이너의 객체에서 조작해야 할 필요가 있습니다. 예를 들어, 드로잉의 속성을 설정해야한다면 RoomContainer> 데스크 객체> 그리기로 이동해야합니다. 배열에서 적절한 그리기 객체를 찾아 객체를 반환하는 메소드가 있어야합니다. 그런 다음 일단 객체가 반환되면 속성/메소드가 호출됩니까? – 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