2012-04-25 4 views
3
public abstract class Character 
{ 
    protected Weapon weapon; 

    public string Name; 
    public int Health = 10; 
    public int Strength; 

    public Character() 
    { 
    } 

    public void Attack() 
    { 
     weapon.useweapon(); 
    } 
} 

public class Warrior : Character 
{ 
    public Warrior() 
    { 
     weapon = new Sword(); 
     Health = 10; 
     Strength = 25; 
    } 

    public void SetWeapon(Weapon newweapon) 
    { 
     weapon = newweapon; 
    } 

} 

public class Wizard : Character 
{ 
    public Wizard() 
    { 
     weapon = new Spell(); 
     Health = 15; 
     Strength = 10; 
    } 
} 

위에서 볼 수 있듯이 추상 문자 클래스와 두 개의 문자 하위 클래스가 있습니다. 이 프로그램에서는 전사 만이 무기를 바꿀 수 있습니다.자체 클래스 대신 상속 된 추상 클래스로 객체를 선언하는 이유

Warrior Zizo = new Warrior(); 
Wizard Hang = new Wizard(); 
Zizo.SetWeapon(new Axe()); //I can only use this method in this implementation 

는 IS 무엇 -하는 대신

Character Zizo = new Warrior(); 
Character Hang = new Wizard(); 

:이 사용하는 것이 왜 지금, 내가, 코드 자체를 논의하기 위해 찾는 게 아니에요 내가 알고 싶은 것은 내 구현 코드에서, 두 클래스 간의 차이점과 추상 클래스로 객체를 선언하면 어떤 이점을 얻을 수 있습니까?

+1

OO 개념에 대한 확고한 이해가없는 것 같습니다. 주제에 관한 책을 읽을 때 약간의 시간을 투자 할 가치가 있습니다. – R0MANARMY

+0

왜 그렇게 생각하는지 말해 주시겠습니까? – Zizo47

답변

4

클라이언트 코드는 최소한으로 필요한 인터페이스 또는 추상 클래스 정의를 사용해야합니다. 주로 코드를 느슨하게 결합하기 위해이 작업을 수행합니다. 귀하의 예에서 호출 코드가 Attack() 일 때만 수행되었지만 실행, 구현 또는 어떤 특정 유형 (예 : Warrior, Wizard 등)이 공격 중인지 염려하지 않으면 abstract Character 클래스를 사용해야합니다.

반드시이 특정 구현 또는 구체적인 클래스에 대한 지식이 있어야하는 경우 명시 적으로 사용하는 것이 적절합니다.

+0

IAttack 인터페이스가 충분해야합니다. – MikeSW

3

당신이 얻는 것은 그것이 공개적으로 노출 된 Character 유형의 멤버와 상호 작용할 수있는 코드를 그 캐릭터가 무엇이든 상관없이 모든 문자 유형에 쓰는 것입니다.

예는 :

public void AttackAndHeal(Character character) 
{ 
    character.Attack(); 
    character.Health++; 
} 

Warrior zizo = new Warrior(); 
Wizard hang = new Wizard(); 

AttackAndHeal(zizo); 
AttackAndHeal(hang); 
+0

상속을 허용합니다. 내가 알고 싶은 것은 왜 The Character라고 선언하는 것입니까? – Zizo47

+0

실제로 그것은 상속이 아니라 오히려 다형성입니다. 상속을 사용하면 부모로부터 유형을 파생시킬 수 있습니다. 다형성 (Polymorphism)은 유형이 다른 유형 (상위 또는 구현 된 인터페이스)으로 취급되도록 허용하는 것입니다. 즉, 특정 유형을 직접 인스턴스화하여 로컬 변수에 할당하는 경우 상위 클래스 사용시 이점이 없습니다. 메소드, 복합 유형, 팩토리 메소드, 종속성 삽입, 제네릭 등으로 작업하는 경우 상위 유형을 사용하면 많은 이점이 있습니다. –

1

항상 그런 식으로 사용할 것이라는 것을 알고 있다면 필요 없습니다. 그러나 종종 캐릭터의 유형을 추상화하고 모든 캐릭터가 내포하는 액션 만 수행하려고합니다.

사람이 화면 중앙에 H 폭탄을 떨어 뜨렸다 고 가정 해 봅시다. 캐릭터가 위자드인지 워리어스인지는 상관 없습니다. 모두 죽음에 이르게되므로, 킬이나 다른 방법으로 전화하면됩니다.

+4

게시물에 서명 할 필요가 없습니다. 나는 당신을 위해 그 편집을 만들었습니다. – Yuck

1

당신은 WarriorWizard의 일반적인 컬렉션이하고 CharacterZizo를 선언함으로써 Character 클래스

var characters = new List<Character>(); 
characters.Add(new Warrior()); 
characters.Add(new Wizard()); 
foreach (var c in characters) 
{ 
    //use members exposed by c 
} 
+0

내가 말했듯이, 나는 단지 코드에 대한 개선점을 찾고 있지 않다. 어쨌든 고마워요. – Zizo47

+2

@ Zizo47 그가 개선점에 대해 이야기하고 있다고 생각하지 않습니다. 객체를 추상적 인 유형으로 취급하고 싶을 때의 예입니다. 컬렉션의 일부 작업을 수행하려는 경우 – R0MANARMY

0

의 회원을 재사용 할 수 있습니다, 당신은 지금 ZizoCharacter 개체의 모든 유형을 지정할 수 있습니다. 불행하게도, 이것은 또한 Character에 대해 명시 적으로 선언 된 속성과 함수 만 호출하도록 제한합니다. Warrior에 대한 Zizo의 모든 항목을 호출하려면 먼저 전송해야합니다.

0

기본 클래스와 하위 클래스에 동일한 이름의 일반 메소드 (예 : 무시되지 않음)가있는 경우 객체의 변수를 기본 클래스로 입력하면 기본 클래스의 메소드가 다음과 같이 선택됩니다. if 메서드가 호출됩니다. 그것은 당신이 그 행동을 찾는다면 그것을 문자로 타이핑 할 이유가 될 것입니다.캐릭터를 매개 변수로 요구하는 메소드에 전사를 추가하거나 전달하면 자동으로 Character로 캐스팅됩니다 (생각할 수 있습니다). 캐릭터로 전사를 입력하면 코드가 작아지기 쉽습니다. 문자 유형이 필요하거나 목록에 추가 할 수 있습니다.

관련 문제