2012-01-23 6 views
2

모두 좋은 하루.배열의 추상 클래스의 파생 클래스

몇 가지 기본 추상 클래스의 파생 클래스를 만들고 사용하는 것에 대한 질문이 있습니다.

어떻게 작동하는지 이해할 수 없습니다.

내 목표 : 있어야 할 기능을 정의한 기본 클래스를 만들고 다른 파생 클래스를 만듭니다. 그런 다음 기본 클래스의 배열을 만들고 다른 파생 클래스를 인스턴스화합니다.

abstract class UIElement 
{ 
    //constructor 
    abstract public UIElement(); 
    //draw element 
    abstract public void Draw(int mouseX, int mouseY); 
    //checks if the element is pointed at by mouse 
    abstract public Boolean IsPointed(int mouseX, int mouseY); 
    //defines what happens when clicked 
    abstract public void Click(int mouseX, int mouseY); 
    //destructor 
    abstract public ~UIElement(); 
} 

그런 다음 여러 파생 클래스를 만들고 그런 식으로 할 :

UIElement[] qwe = new UIElement[3]; 
qwe[0] = new UIElementButton(); 
qwe[1] = new UIElementLabel(); 
qwe[2] = new UIElementSomethingElse(); 

1) 나는 결정적인를 찾을 수 없기 때문에 그것을 할 수있는 적절한 방법은 무엇 예를 들어

답변 또는 그것을 설명 할 기사 ...

2) 클래스 변수는 어디에 선언해야합니까 : 기본 클래스 또는 파생?

3) 파생 클래스가 다른 경우 변수가 다른 경우 어떻게 처리해야합니까?

4) 파생 클래스는 다른 인수를 포함하여 다른 생성자를 가질 수 있습니까?

아래 댓글에서
+0

실제로 명확하지는 않지만 실제로 무엇을하고 있습니다. – kkm

+0

그게 뭐가 잘못 됐니? 귀하의 코드가 올바른 것 같습니다. 제가 지적하고자하는 유일한 사실은 추상 소멸자에 대한 사용이 거의 없다는 것입니다. 대신에'IDisposable'을 대신 구현해야합니다. –

+0

@kkm, 결코 덜 작동하지 않습니다 :) – NewProger

답변

6

, questionner은 UIElement에 기반을 선언하는 추상 클래스

보기의 일반적인 모범 사례 및 정확성 관점에서

, 당신 에게서는와 상속의 hierachies을 작성하기위한 최상의 방법에 대한 조언을 찾고있다 생성자와 추상화자가없는 클래스. 예 :

public abstract class UIElement 
{ 
    //constructor 
    protected UIElement(); 
    //draw element 
    public abstract void Draw(int mouseX, int mouseY); 
    //checks if the element is pointed at by mouse 
    public abstract bool IsPointed(int mouseX, int mouseY); 
    //defines what happens when clicked 
    public abstract void Click(int mouseX, int mouseY); 
} 

당신이 수 후 당신은 위의에 따라 파생 된 클래스를 정의하는 경우, 당신은 기본 유형의 배열로 요소와 저장소를 인스턴스화 할 수 올바른

public class UIElementButton : UIElement 
{ 
    // Optional - create parameterless constructor and 
    // explicitly call base constructor 
    public UIElementButton() : base() 
    { 
    } 

    // Mandatory - must override abstract methods 
    public override Draw(int mouseX, int mouseY) 
    { 
    } 

    // Mandatory - must override abstract methods 
    public override Boolean IsPointed(int mouseX, int mouseY) 
    { 
    } 

    // Mandatory - must override abstract methods 
    public override void Click(int mouseX, int mouseY) 
    { 
    } 
} 

을 다음과 같이 파생 클래스를 구현 다음과 같습니다 :

UIElement[] qwe = new UIElement[3]; 
qwe[0] = new UIElementButton(); 
qwe[1] = new UIElementLabel(); 
qwe[2] = new UIElementSomethingElse(); 

qwe[0].Click(1, 2); // Invokes UIElementButton.Click 
qwe[1].Draw(3, 4); // Invokes UIElementLabel.Draw 

또한 WPF에 정의 된 UIElement 클래스가 있어야합니다. 유형에 대한 네임 스페이스를 정의하는 경우 문제가되지 않지만 사용자 정의 유형을 구별하기 위해보다 명확한 유형 이름 (예 : BaseElement)을 고려하십시오. 의견의 쿼리에 대해서는


:

추상 클래스의 사용에 대한 자세한 조언을 들어, All about abstract classes - Codeproject를 참조하십시오. - 클래스 변수는 어디에서 선언해야합니까? 기본 클래스 또는 파생 클래스? - 다른 파생 클래스에 다른 변수가있는 경우 어떻게 처리해야합니까? - 파생 클래스가 다른 인수를 포함하여 다른 생성자를 가질 수 있습니까?

이들은 그러나 선발로 내가 말할 수있는, 정말 구글에 다른 질문이나 자신의 연구에 대한 주제입니다

  1. 클래스 변수들이 필요한 범위에서 선언해야합니다. 변수가 Guid _uiElementId이고 파생 형식에서 액세스하려고하는 경우 기본 클래스에서 선언하고 protected으로 표시해야합니다. 당신이있는 경우 UIElementButton의 변수는 Point _mousePoint이라고 만 UIElement에 버튼 괜찮아 private

  2. 로이 마크에두고, 그것을 필요 - 기본 클래스에서 자신의 개인 변수와 보호 변수를 볼 수있는 유형입니다. 이름이 충돌하지 않는지 확인하십시오.

  3. 예.


public class UIElementButton : UIElement  
{  
    private string _buttonText; 

    // Overloaded ctor 
    public UIElementButton(string buttonText) : base() 
    { 
     buttonText = buttonText; 
    } 

    // Default constructor. Mark as private or protected 
    // to hide from external API 
    public UIElementButton() : base() 
    { 
    } 
} 

안부

, 그것은이 문제이지만, 코드가 컴파일되지 않습니다 귀하의 질문에서 명확하지

+0

자세한 설명을 해주셔서 감사합니다. 어떻게 작동하는지 배우려고 할 때 몇 점을 놓친 것 같습니다. 귀하의 답변 덕분에 지금은 그것을 이해할 것 :) 나는 지금 구현하려고합니다. – NewProger

+0

@NewProger 기쁘게 도와 드릴 수 있습니다. 나중에 참조 할 수 있도록 내가 정말로 필요한 것을 추측해야하므로 질문을 더 명확하게 설명하십시오. 다행히 나는 운이 좋은 추측을했다! 제가 도와 드릴 수있는 다른 것이 있습니까? 의견에 게시하십시오. 감사합니다 –

+0

가능한 경우 클래스 변수에 대한 답변 정보에 포함시켜주십시오. 선언 할 위치는 기본 클래스 또는 파생 클래스입니까? 다른 파생 클래스가 다른 변수를 가지고 있다면 어떻게 해결해야합니까? 두 번째 질문은 파생 클래스가 다른 인수를 포함하여 다른 생성자를 가질 수 있습니까? 죄송합니다. 시간을내어 주셔서 감사합니다.하지만 적어도 답을 선택하고 "올리십시오". – NewProger

0

. C#에서는 abstract 생성자를 가질 수 없습니다. 그리고 파이널 라이저는 public이나 abstract이 될 수 없습니다. 둘 중 하나를 가질 필요가 없습니다. 간단히 제거 할 수 있습니다.

그리고 관리되지 않는 리소스를 처리하지 않으려는 경우가 아니라면 일반적으로 finalizer를 사용하지 않아야합니다. 그리고 필요한 경우 IDisposable도 구현하고 싶을 것입니다.

3

정확하게 추측하면 OP는 C++ 배경에서 제공됩니다. C++과 C# 사이에는 많은 유사점이 있지만 모든 기능이 1 : 1과 일치하는 것은 아닙니다.

당신은 당신의 "기본 클래스"바로 설정 할 수있는 유효한 작업을 모든 자손이 더 코드가없는, 즉, 당신은 인터페이스를 사용해야합니다 :

public interface IUIElement 
{ 
    //draw element 
    void Draw(int mouseX, int mouseY); 
    //checks if the element is pointed at by mouse 
    bool IsPointed(int mouseX, int mouseY); 
    //defines what happens when clicked 
    void Click(int mouseX, int mouseY); 
} 

생성자 또는 필요가 없습니다를 소멸자, 또는 메소드를 public으로 명시 적으로 선언 할 수 있습니다. 인터페이스는 private 메소드/특성을 포함 할 수 없으므로 인터페이스를 구현하는 클래스로 연기됩니다.

이 후, 당신은 (당신을 위해 그 (것)들을 스텁 수있는 비주얼 스튜디오) 같은 클래스를 선언 할 수

public class UIElementButton : IUIElement 
{ 
    public UIElementButton() 
    { 
    ... 
    } 

    void Draw(int mouseX, int mouseY) 
    { 
    ... 
    } 

    bool IsPointed(int mouseX, int mouseY) 
    { 
    ... 
    } 

    void Click(int mouseX, int mouseY) 
    { 
    } 
} 

(배열 포함) 코드의 나머지 부분을 잘 보이는, 그러나 나는 원합니다 배열 대신 목록 표시 :

List<IUIElement> qwe = new List<IUIElement>(); 
qwe.Add(new UIElementButton()); 
qwe.Add(new UIElementLabel()); 
qwe.Add(new UIElementSomethingElse()); 

// some sample usages 
foreach(IUIElement element in qwe) 
{ 
    element.Click(); 
} 

qwe[0].Click() //invokes UIElementButton.Click(); 

//gets all pointed elements 
var pointedElements = qwe.Where(e => e.IsPointed(x,y)); 
+0

설명해 주셔서 감사합니다. 정말 도움이되었습니다. 또한 아니, 난 C++ 배경이 아니야, 주로 PHP에서 웹 프로그래밍을한다. 그런 문제가 발생하지 않는다. 데이터 형식의 배열에 무엇이든 넣을 수 있기 때문에, 내 혼란의 이유가된다. . 어쨌든, 다시 한번 감사드립니다! – NewProger

+0

+1 예를 들어 사용합니다. @NewProger C#은 강력한 형식을 사용하므로 추상화 및 상속 계층 구조를 처리하기 위해 약간 다른 패러다임을 배워야합니다. –

관련 문제