해결된 질문
작성
·
99
답변 2
1
업캐스팅할 이유가 없다면 굳이 할 필요가 없습니다.
override와 new키워드의 차이를 명확히 보여드리고 싶어서 인스턴스를 영상과 같이 만들었을 뿐이에요~
다음은 인스턴스를 만들 때 업캐스팅을 하지 않지만
스타크래프트의 마린과 벌쳐의 공격(Attack) 메서드를 사용할 때 업캐스팅의 좋은 예시 코드입니다.
class Program
{
static void Main(string[] args)
{
// Marine과 Vulture 객체 생성
Marine marine = new Marine();
Vulture vulture = new Vulture();
// Marine이 Vulture를 공격
marine.Attack(vulture);
// Vulture가 Marine을 공격
vulture.Attack(marine);
// Marine이 다시 Vulture를 공격
marine.Attack(vulture);
Console.ReadKey();
}
}
class Unit
{
public string Name { get; set; }
public int Health { get; set; }
public Unit(string name, int health)
{
Name = name;
Health = health;
}
// 데미지를 받는 메서드
public void TakeDamage(int damage)
{
Health -= damage;
if (Health < 0) Health = 0;
Console.WriteLine($"{Name}이(가) {damage}의 피해를 입었습니다. 체력: {Health}");
}
// 가상 메서드: Attack
public virtual void Attack(Unit target)
{
Console.WriteLine($"{Name}이(가) {target.Name}을(를) 공격합니다!");
}
}
// 자식 클래스: Marine
class Marine : Unit
{
public Marine() : base("Marine", 40) { }
// Attack 메서드 오버라이드
public override void Attack(Unit target)
{
base.Attack(target); // 부모 클래스의 Attack 메서드 호출
target.TakeDamage(6); // Marine의 공격력: 6
}
}
// 자식 클래스: Vulture
class Vulture : Unit
{
public Vulture() : base("Vulture", 80) { }
// Attack 메서드 오버라이드
public override void Attack(Unit target)
{
base.Attack(target); // 부모 클래스의 Attack 메서드 호출
target.TakeDamage(20); // Vulture의 공격력: 20
}
}
결과:
Marine이(가) Vulture을(를) 공격합니다!
Vulture이(가) 6의 피해를 입었습니다. 체력: 74
Vulture이(가) Marine을(를) 공격합니다!
Marine이(가) 20의 피해를 입었습니다. 체력: 20
Marine이(가) Vulture을(를) 공격합니다!
Vulture이(가) 6의 피해를 입었습니다. 체력: 68
위 코드처럼 필요 시 업캐스팅을 하시면 되겠습니다.
또 다른 질문이 있으시다면 언제든지 주세요. 감사합니다 ^^
업캐스팅은 다형성과 관련이 깊습니다.
다형성(Polymorphism): 하나의 인터페이스나 클래스를 통해 다양한 타입의 객체를 처리할 수 있는 능력.
만약 아래 함수의 매개변수가 Unit 이 아닌 Vulture 타입만 받는다고 가정을 해볼게요.
// 벌쳐만 공격할 수 있는 메서드
public void Attack(Vulture target)
{
base.Attack(target); // 부모 클래스의 Attack 메서드 호출
target.TakeDamage(6); // Marine의 공격력: 6
}
그렇다면 이 어택 함수는 벌쳐만 공격할 수 있는 함수가 되는 것 입니다.
만약 다형성을 활용하지 못한다면
마린이 히드라를 공격한다고 가정하면 히드라 공격 함수를 만들어야 하고,
마린이 질럿을 공격한다고 가정하면 질럿 공격 함수를 만들어야 합니다.
유닛이 100가지라면 100가지의 함수를 모두 구축하는 것은 올바른 프로그래밍이라고 보긴 어렵겠지요.
그래서 단 하나의 함수로 Unit에 대한 공격 메서드를 하나로 정의할 수 있습니다.
public override void Attack(Unit target)
{
base.Attack(target); // 부모 클래스의 Attack 메서드 호출
target.TakeDamage(6); // Marine의 공격력: 6
}
따라서 위 메소드 처럼 업캐스팅을 사용하게 되면 Unit을 상속한 모든 대상을 공격할 수 있는 하나의 메서드만 정의해도 사용이 가능하다는 것입니다 ㅎㅎ
따라서 아래와 같이
Unit marine = new Marnie();
Unit vulture = new Vulture();
단순히 인스턴스를 생성할 때 부터 업캐스팅을 하는것은 크게 의미가 없을 수도 있습니다.
아래의 Attack메서드를 호출할 때
Marine marine = new Marnie();
Vulture vulture = new Vulture();
marine.Attack(vulture) // 여기서 벌쳐는 메서드의 인수로 들어가면서 업캐스팅이 됩니다.
업캐스팅이 적용되게 됩니다.
업캐스팅의 장점은 아래처럼 형변환을 굳이 하지 않아도 된다는 점도 있습니다.
marine.Attack(vulture) == marine.Attack((Unit)vulture)
0
안녕하세요, 인프런 AI 인턴입니다. Lucas님.
C#를 포함한 여러 객체 지향 프로그래밍 언어에서 upcasting을 사용하는 이유는 다양합니다. 다수의 경우, upcasting
은 확장성 및 유연성을 높이는 데 중요한 역할을 합니다. 다음은 upcasting을 사용하는 주요 이유들입니다:
다형성 활용: upcasting을 통해 여러 파생 클래스 객체를 부모 클래스 타입의 변수에 담아서 사용할 수 있습니다. 이는 프로그램을 더 유연하게 만들며, 다양한 객체들이 같은 인터페이스를 통해 상호작용할 수 있도록 해줍니다.
호환성 및 일반성: 부모 클래스 타입으로 객체를 처리함으로써, 코드는 특정 파생 클래스에 종속되지 않으며, 다양한 파생 클래스가 동일한 코드 블록을 공유할 수 있습니다.
코드의 단순화: 여행과 같은 경우, 동일한 타입의 객체 배열이나 컬렉션을 쉽게 생성하여 처리할 수 있게 해줍니다.
upcasting이 접근 제한자(private)와 직접적인 관계는 없지만, 더 높은 수준의 흥미로운 구조나 특정 클래스들 간의 상호작용을 가능하게 하여 결과적으로 접근 제한자를 효과적으로 관리하는 데 도움을 줄 수 있습니다.
관련된 설명을 포함한 추가 질문이 필요하시면 아래 링크들도 좋은 참고가 될 수 있습니다. 비슷한 주제에 대해 더 자세히 읽어보실 수 있습니다:
저는 질문자님의 이해를 돕고자 지식공유자님의 기존 답변을 참고하여 유사한 답변 링크를 추천해드리고 있습니다.
현재 베타 기능으로 답변이 만족스럽지 않을 수 있는 점 양해 부탁드립니다. 🙏
추가적으로 궁금한 점이 있으시면, 이어서 질문해 주세요. 곧 지식공유자께서 답변해 주실 것입니다.
답변 감사합니다! 살짝 헷갈리는 부분이 예시로 주신 마린과 벌처의 업캐스팅으로 인스턴스를 만들 때 Unit으로 클래스를 명시해야 하는게 아닌가 했습니다.
Unit marine = new Marnie(); Unit vulture = new Vulture();
써주신대로 업캐스팅하지 않지만 업캐스팅의 좋은 예시라는게 제 머리로 이해가 되지 않습니다 ㅜㅜㅜ
업캐스팅의 정확한 의미를 제가 몰라서 그런게 아닌가 합니가