프로그래밍 언어/C#

C# 프로그래밍 언어에서 인터페이스와 추상 클래스 차이점 및 사용법

eco7T 2024. 10. 7. 15:37
반응형

C# 프로그래밍 언어에서 인터페이스와 추상 클래스는 객체 지향 프로그래밍의 핵심 개념 중 하나입니다. 이 두 가지 개념은 코드의 구조화, 재사용성, 그리고 유지보수성을 향상하는 데 중요한 역할을 합니다. 이 학습서를 통해 인터페이스와 추상 클래스의 개념, 사용법, 그리고 실제 적용 방법에 대해 상세히 알아보겠습니다.

C# 인터페이스와 추상 클래스
C# 인터페이스와 추상 클래스

 

C# 인터페이스와 추상 클래스

  인터페이스 (Interface)

인터페이스는 클래스가 구현해야 하는 메서드, 프로퍼티, 이벤트 등의 멤버를 정의하는 계약(contract)과 같은 역할을 합니다. 인터페이스는 이러한 멤버들의 선언만 포함하고 있으며, 실제 구현은 포함하지 않습니다. 클래스가 인터페이스를 구현할 때, 해당 클래스는 인터페이스에 정의된 모든 멤버를 반드시 구현해야 합니다.

 

반응형

 

인터페이스 정의하기

인터페이스를 정의할 때는 다음과 같은 규칙을 따릅니다.

  • `interface` 키워드를 사용합니다.
  • 인터페이스 이름은 대문자 'I'로 시작하는 것이 관례입니다.
  • 메서드, 프로퍼티, 이벤트 등의 멤버를 선언만 하고 구현은 하지 않습니다.
  • 모든 멤버는 기본적으로 public입니다.
public interface IExampleInterface { void DoSomething(); string GetSomething(); int SomeProperty { get; set; } }

 

인터페이스 구현

클래스에서 인터페이스를 구현할 때는 다음과 같은 방법을 사용합니다.

  1. 클래스 선언부에 `: 인터페이스이름`을 추가합니다.
  2. 인터페이스에 정의된 모든 멤버를 구현합니다.

 

  코드 예시

public class ExampleClass : IExampleInterface { public void DoSomething() { Console.WriteLine("Doing something"); } public string GetSomething() { return "Something"; } public int SomeProperty { get; set; } }

 

인터페이스의 장점

  • 다중 구현: C#에서 클래스는 여러 인터페이스를 동시에 구현할 수 있습니다. 이는 단일 상속의 제한을 극복하는 방법을 제공합니다.
  • 계약 보장: 인터페이스는 클래스가 특정 기능을 반드시 구현하도록 강제합니다.
  • 느슨한 결합: 인터페이스를 사용하면 구체적인 구현에 의존하지 않고 프로그래밍할 수 있어, 코드의 유연성이 향상됩니다.
  • 테스트 용이성: 인터페이스를 사용하면 목(mock) 객체를 쉽게 만들 수 있어 단위 테스트가 용이해집니다.

 

인터페이스 예시 코드

동물 소리 내기 다음은 동물의 소리를 내는 기능을 구현하는 예시입니다.

public interface IAnimal { string MakeSound(); string Name { get; set; } } public class Dog : IAnimal { public string Name { get; set; } public Dog(string name) { Name = name; } public string MakeSound() { return "멍멍!"; } } public class Cat : IAnimal { public string Name { get; set; } public Cat(string name) { Name = name; } public string MakeSound() { return "야옹~"; } } // 사용 예시 public class Program { public static void Main(string[] args) { IAnimal dog = new Dog("멍멍이"); IAnimal cat = new Cat("야옹이"); Console.WriteLine($"{dog.Name}의 소리: {dog.MakeSound()}"); Console.WriteLine($"{cat.Name}의 소리: {cat.MakeSound()}"); } }

이 예시에서 `IAnimal` 인터페이스는 모든 동물이 가져야 할 기본적인 특성(이름)과 행동(소리 내기)을 정의합니다. `Dog`와 `Cat` 클래스는 이 인터페이스를 구현하여 각자의 방식으로 소리를 냅니다. 이렇게 함으로써 다양한 동물 클래스를 쉽게 추가할 수 있고, 모든 동물 객체를 `IAnimal` 타입으로 다룰 수 있어 코드의 재사용성과 확장성이 높아집니다.

 

 

  추상 클래스 (Abstract Class)

추상 클래스는 하나 이상의 추상 메서드를 포함할 수 있는 불완전한 클래스입니다. 추상 메서드는 선언만 있고 구현이 없는 메서드를 말합니다. 추상 클래스는 직접 인스턴스화할 수 없으며, 다른 클래스가 이를 상속받아 구체화해야 합니다.

 

추상 클래스 정의하기

추상 클래스를 정의할 때는 다음과 같은 규칙을 따릅니다.

  • `abstract` 키워드를 클래스 선언 앞에 붙입니다.
  • 추상 메서드는 `abstract` 키워드를 사용하여 선언하고, 구현부는 작성하지 않습니다.
  • 추상 클래스는 일반 메서드와 추상 메서드를 모두 포함할 수 있습니다.
public abstract class AbstractExample { public abstract void AbstractMethod(); public void ConcreteMethod() { Console.WriteLine("This is a concrete method."); } }

 

 

추상 클래스 상속받기

추상 클래스를 상속받는 클래스는 다음과 같은 규칙을 따라야 합니다.

  1. 상속받는 클래스 선언부에 `: 추상클래스이름`을 추가합니다.
  2. 추상 클래스의 모든 추상 메서드를 구현해야 합니다.
  3. `override` 키워드를 사용하여 추상 메서드를 구현합니다.

  예시 코드

public class ConcreteClass : AbstractExample { public override void AbstractMethod() { Console.WriteLine("This is the implementation of the abstract method."); } }

 

추상 클래스의 장점

  • 공통 기능 구현: 추상 클래스는 자식 클래스들이 공유할 수 있는 공통 기능을 구현할 수 있습니다.
  • 부분적 구현: 일부 메서드는 구현하고, 일부는 추상 메서드로 남겨둘 수 있어 유연성이 높습니다.
  • 계층 구조: 복잡한 클래스 계층 구조를 설계할 때 유용합니다.
  • 확장성: 새로운 기능을 추가할 때 기존 코드를 변경하지 않고도 확장할 수 있습니다.

 

추상 클래스 예시 코드

도형 면적 계산하기 다음은 다양한 도형의 면적을 계산하는 예시입니다.

public abstract class Shape { public abstract double CalculateArea(); public void PrintArea() { Console.WriteLine($"이 도형의 면적은 {CalculateArea()}입니다."); } } public class Circle : Shape { private double radius; public Circle(double radius) { this.radius = radius; } public override double CalculateArea() { return Math.PI * radius * radius; } } public class Rectangle : Shape { private double width; private double height; public Rectangle(double width, double height) { this.width = width; this.height = height; } public override double CalculateArea() { return width * height; } } // 사용 예시 public class Program { public static void Main(string[] args) { Shape circle = new Circle(5); Shape rectangle = new Rectangle(4, 6); circle.PrintArea(); rectangle.PrintArea(); } }

 

 

이 코드에서 `Shape` 추상 클래스는 모든 도형이 가져야 할 `CalculateArea` 메서드를 추상 메서드로 정의하고, 공통으로 사용할 수 있는 `PrintArea` 메서드를 구체적으로 구현합니다. `Circle`과 `Rectangle` 클래스는 `Shape`를 상속받아 각자의 방식으로 면적을 계산합니다. 이렇게 함으로써 새로운 도형 클래스를 쉽게 추가할 수 있고, 모든 도형 객체를 `Shape` 타입으로 다룰 수 있어 코드의 재사용성과 확장성이 높아집니다.

반응형