오늘은 프로젝트에서 스킬 부분을 구현했다. 스킬 부분을 구현할 때 가장 핵심이라고 생각하는 인터페이스(Interface)에 대해 알아보자.
인터페이스는 클래스의 다중 상속이 허용되지 않는 C#에서 매우 중요한 요소이다. 왜냐하면 인터페이스는 다중 상속이 가능하기 때문이다.
<인터페이스란?>
추상 클래스보다 높은 수준의 추상 멤버로만 구성된 클래스를 뜻한다. 그래서 인터페이스는 모든 멤버들이 abstract의 속성을 가지게 되며, public으로 간주된다.
간단하게 설명하면 인터페이스는 상속받을 클래스에게 틀을 제시한다고 생각하면된다.
인터페이스는 다음과 같은 특징을 가진다.
1. 메소드, 이벤트, 인덱서, 프로퍼티만 가질 수 있다. (변수 불가능)
2. 모든 멤버들이 public으로 간주되며, 접근 제한 한정자를 사용할 수 없다.
3. 자신을 상속받는 클래스에게 오버라이딩을 강제한다. (상속받으면 무조건 구현해야된다는 뜻)
4. 자식 클래스에서 구현할 메소드들은 public으로 선언해야한다.
5. 구현부가 존재하지 않는다.
6. 인스턴스를 만들 수 없지만, 인터페이스를 상속받는 클래스의 인스턴스를 만드는 것은 가능하다.
7. 클래스는 인터페이스를 다중 상속 받을 수 있다.
이러한 특징을 이해하고 인터페이스를 활용하여 스킬을 만들어보자.
먼저 오늘 작성한 코드의 일부분이다.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; namespace TextRPG { // 스킬 기본 구성 인터페이스 public interface ISkill { string name { get; set;} int mpValue { get; set; } float damageValue { get; set; } string description { get; set; } // 스킬의 정보를 보여주는 함수 void SkillInfo(); // 스킬 사용 함수 void Use(); } // 알파 스트라이크 스킬 클래스 public class AlphaStrike : ISkill { public string name { get; set; } public int mpValue { get; set; } public float damageValue { get; set; } public string description { get; set; } public AlphaStrike() { name = "알파 스트라이크"; mpValue = 10; damageValue = 2; description = $"공격력 * {damageValue} 로 하나의 적을 공격합니다."; isRandom = false; } public void SkillInfo() { Console.WriteLine($"{name} - MP {mpValue}"); Console.WriteLine(description); } public void Use() { // 스킬 사용 } } // 더블 스크라이크 스킬 클래스 public class DoubleStrike : ISkill { public string name { get; set; } public int mpValue { get; set; } public float damageValue { get; set; } public string description { get; set; } public DoubleStrike() { name = "더블 스트라이크"; mpValue = 15; damageValue = 1.5f; description = $"공격력 * {damageValue} 로 2명의 적을 랜덤으로 공격합니다."; isRandom = true; } public void SkillInfo() { Console.WriteLine($"{name} - MP {mpValue}"); Console.WriteLine(description); } public void Use() { // 스킬 사용 } } }
뭔가 복잡해보이는데 사실 별거 없는 코드이다!
위에서부터 훑어보면
ISkill 인터페이스에서 해당 인터페이스를 상속 받을 클래스들에게 name, mpValue, damageValue, description 이라는 프로퍼티와 SkillInfo(), Use()라는 함수의 틀을 제공한다.
틀을 제공한다는 것은 선언부만 작성하고 구현부를 작성하지 않는 것을 뜻한다.
이렇게 ISkill 인터페이스를 상속받은 AlphaStrike 클래스와 DoubleStrike 클래스에서 ISkill에서 제공된 틀을 모두 구현 하면 된다. (ISkill에서 제시한 틀을 구현하지 않으면 오류가 난다.)
그리고 인터페이스를 상속받아서 만들면 클래스가 달라도 인터페이스로 묶어서 하나의 리스트에서 관리할 수 있기 때문에 정말 편하다!
skillList = new List<ISkill> { new AlphaStrike(), new DoubleStrike() };
다음부터 아이템이나 몬스터같은 중복되는 부분이 있는 class를 만들 때 적극적으로 인터페이스를 활용하자!