2012-03-26 3 views
0

그래서 상속 및 인터페이스에 대한 아이디어가 새로 생겨서 어떻게해야 하는지를 잘 모르겠습니다.C#에서 상속을 사용하여 함수를 공유하십시오.

캐릭터의 위치, 회전 방향, 질감을 정의한 캐릭터 클래스가 있습니다. 플레이어 클래스와 Enemy 클래스로이 클래스를 상속하고 싶습니다. 따라서 플레이어에 대해 동일한 이동 및 그리기 클래스를 사용할 수 있습니다. AI를 제어하는 ​​추가 기능을 추가하면서 적을 공격 할 수 있습니다.

정적 플레이어 클래스에 의해 상속되지만 Player 클래스를 통해 위치에 액세스 할 수없는 문자 클래스가 있으므로 개체 참조가 필요하다고 말합니다.

그렇다면 상속을 사용하여 플레이어와 AI간에 함수를 공유하면서도 하위 클래스를 통해 문자 클래스의 변수에 액세스 할 수 있습니까?

+2

코드를 알려주십시오. – RedFilter

+5

* 정적 * 플레이어 클래스? 아니, 아니. 테스트하기가 어렵고 연장하기가 어렵습니다. 플레이어 클래스를 일반 클래스로 만들고 '객체 참조 필요'오류와 앱 테스트/확장의 어려움이 사라집니다. – tvanfosson

+1

'Player' 클래스가'Character'를 상속 받으면 어떻게'static'이 될 수 있습니까? 'static' 클래스는'object' 이외의 것을 상속받을 수 없습니다. – BACON

답변

2

는 추상 클래스가 아닌 정적 클래스로 기본 클래스를 구현합니다. 정적 메서드는 실제 개체에 대한 참조없이 개체의 속성이나 필드에 액세스 할 수 없습니다.

+0

감사합니다. 도움이되었습니다. 캐릭터 오브젝트를 상속했기 때문에 Character 오브젝트 대신 Player 오브젝트를 사용할 수 있다고 생각합니다. – Joel

+0

"in place of"가 무슨 뜻인지 잘 모르겠지만 Player가 Character로부터 상속받은 경우 모든 Player 인스턴스도 Character 인스턴스임을 의미합니다. –

+0

예, 감사합니다. 예를 들어 플레이어 개체를 문자 목록에 추가 할 수 있습니다. – Joel

0

개인 클래스와 달리 기본 클래스의 속성을 protected로 표시하면 파생 클래스가 액세스 할 수 있습니다.

+0

함수에서 Character 클래스를 사용하려고하면이 문제가 발생합니다. – Joel

3

하위 클래스가 변수에 액세스 할 수있게하려면 상위 "Character"클래스에 "private"가 아닌 "protected"로 선언 된 비공개 멤버가 있어야합니다. 그 후에 "class"키워드를 사용하여 클래스의 현재 인스턴스를 참조하는 "this"를 사용하는 것과 비슷한 방법으로 부모를 참조합니다. 예를 들어

:

//note: abstract is not a pre-requisite for inheritance 
abstract class Character 
{ 
    protected float x; 
    protected float y; 
    protected float z; 
    //etc etc 
} 

public class AIBasic : Character 
{ 
    public void move() 
    { 
     //purely an example 
     base.x++; 
     base.y++; 
     base.z++; 
    } 
} 
+0

기본 키워드에 대해 알려 주셔서 감사합니다. 염두에 두겠습니다. – Joel

2

상속은이 문제에 대한 최선의 해결책이 아닙니다. 대신 IoC (Inversion of Control)를 사용하고 별도의 드로잉 및 이동 클래스를 생성하는 것이 좋습니다. 그런 다음 단일 문자 인스턴스로 구성하십시오.

Ninject는 내가 좋아하는 IoC 도구 ​​중 하나이며 튜토리얼은 다소 완전합니다. 사실 그것은 매우 간단하지만 일반적인 게임 캐릭터 클래스를 보여줍니다.

https://github.com/ninject/ninject/wiki/Injection-Patterns

+0

나는이 프로젝트를 완료 할 시간이별로 없지만 그걸 가지고 놀기에는 좀 더 시간이 필요할 때 내가보기에 그 페이지를 즐겨 찾기에 추가했다. 감사합니다. – Joel

1

그래서 가장 먼저 할 일은 기본 클래스를 정의하는 것입니다. 당신이 그것을 인스턴스화 결코하려는 경우, 당신은 추상 클래스를 만든 다음 속성과 메소드가 오버라이드 (override) 할 수 있습니다 : 정적 클래스에서 '상속'에

대답에
// Marking the properties as virtual allow you to override their behaviour 'by design'. Their normal 
// behaviour will continue to work if you choose not to 
public abstract class Character 
{ 
    protected virtual Point Position { get;set; } 
    protected virtual int Direction {get;set; } 
    protected virtual Image Texture { get;set; } 
    protected virtual bool Visible { get; set; } 

    // Define methods you would like to partially implement or let the other class do: 
    public virtual void Rotate(int directionInDegrees) 
    { 
      this.Direction += directionInDegrees; 
    } 

    public abstract void Draw(); 
} 

// Then use inheritance to create the classes based on this 
public class Player : Character 
{ 
    public override void Rotate(int directionInDegrees) 
    { 
      // Implement character specific rotate 
    } 

    public void Draw() 
    { 
      // Must implement Draw(), so that we can instantiate the class properly. 
      // All methods of an abstract class must be implemented before a class is deemed 
      // valid to use instantiate directly. 
    } 
} 

public class Enemy : Character 
{ 
    public override void Rotate() 
    { 
    } 
} 

, 당신은이 작업을 수행 할 수 없습니다. static 메서드는 개체의 인스턴스가 아니라 클래스에 속하므로 상속 될 수 없습니다. 그것들은 오버라이드 될 수 있지만 (당신이 그것을 오버라이드한다는 것을 나타 내기 위해 new 키워드를 사용함으로써), 당신이 만드는 모든 클래스에 이것을 구현해야 할 것입니다.

기본적으로 메서드를 재정의하려면 비 정적 메서드를 작성해야합니다.

+0

고맙습니다. 매우 도움이됩니다. – Joel

관련 문제