상속
다른 클래스의 멤버를 이어받는 기능으로, 기본 클래스와 파생클래스가 1:N의 관계를 갖는다.
- 파생클래스의 객체는 기본 클래스의 private을 제외한 멤버를 사용할 수 있다.
- 기본 클래스(부모 클래스): 상속하는 바탕이 되는 클래스
- 파생 클래스(자식 클래스): 상속하여 만든 클래스
sealed
: 다른 클래스에서 상속 불가능하도록 하는 키워드.virtual
메서드를override
한 메소드에도 지정 가능base
: 상속 원본에 인수를 전달하는 키워드 -> 기본 클래스의 인수가 있는 생성자를 호출base
사용하지 않으면: 상속 원본의 인수가 없는 생성자 호출- 이름의 은폐가 일어날 때, 은폐된 기본 클래스 멤버를 파생 클래스 안에서 사용할 때에도 이용
->base.a
: 기본클래스 필드의 a
using System;
class Calc1{
public int x;
public Calc1(int a, int b) { x = a+b;}
}
class Calc2 : Calc1 {
public Calc2(int c, int d) : base(c, d) {}
}
class Calc3 {
public static void Main(){
Calc2 calc2 = new Calc2(1, 2);
Console.WriteLone(calc2.x); // 결과: 3
}
}
다중상속을 허용하는 C++과는 다르게, C#은 단일상속을 원칙으로 한다.
- 단, 구현을 생략한 선언만 물려주는 인터페이스는 다중상속을 허용한다.
- C++에서는 '가상상속'이라는 개념을 사용해 다중상속을 계속 이끌어나간다.
- 죽음의 다이아몬드 문제: 하나의 부모 클래스를 두 개의 자식 클래스가 상속받고, 이 두개의 자식 클래스를 다시 하나의 자식 클래스가 상속하는 예시.
이 때, 마지막 상속 개체가 사용할Bark()
메서드가 어느 쪽의 것인지 모호해지는 모호성이 죽음의 다이아몬드 문제의 핵심이다. 프로그래밍 언어는 같은 구문이 두 가지 이상의 의미로 해석되지 않아야 하기 때문이다. 다중 상속은 이러한 문제를 야기할 수 있으므로 C#에서는 다중상속을 허용하지 않는다.- 파생 클래스는 기본 클래스의
virtual
멤버를 override하여 사용할 수 있으며(선택),abstract
멤버는 override해야 한다(필수).
- 파생 클래스는 기본 클래스의
다형성
한 객체나 메소드가 다양한 형태를 가지는 것
- 파생 클래스 객체: 기본 클래스의 객체로 취급할 수도, 파생 클래스 객체로 취급할 수도 있다.
- 이 때, 형 변환은 자식type의 참조변수 -> 부모type의 참조변수, 또는 그 반대의 형변환만 가능하다.
📌 단, 다운 캐스팅은 업 캐스팅을 시행한 변수에서만 시행 가능. 다른 경우에 사용시InvalidCastException
예외 발생- 업 캐스팅: 자식type의 참조변수를 부모type의 참조변수로 변환 (형변환 생략 가능)
- 다운 캐스팅: 부모type의 참조변수를 자식type의 참조변수로 변환(형변환 생략 불가)
🌟 upcasting했을 때는 child 객체의 필드를 사용할 수 없다.
: 이 때, child에서override
한 메소드가 있다면 parent의 것이 아닌 child의 것을 사용반대로, upcasting한 것을 다시 downcasting을 했을 때는 child의 필드를 다시 사용 가능
: 이 때, 상속을 받았으므로 parent의 필드도 사용 가능
class A{
public int m;
public virtual void p(){}
}
class B: A {
public int n;
public override void p(){}
}
class Program{
static void Main(){
A a = new B(); // 업 캐스팅
B b = null;
b = (b)a; // 다운 캐스팅
}
}
as
연산자와is
연산자를 이용한 형변환
오류를 발생시키지 않고 형변환이 가능한지 확인할 수 있는 방법!as
: 형변환이 가능하면 지정된 타입의 인스턴스를 반환, 가능하지 않으면 null 반환
-> null 반환 여부를 통해 형변환이 성공했는지 알 수 있다!is
: 형변환의 가능 여부를 bool 타입의 결과값으로 반환.
-> 참조 형식 뿐 아니라 값 형식에도 사용 가능
- 인터페이스를 이용한 다형성
- 인터페이스는 그것을 구현한 클래스의 부모라고 할 수 있다.
-> 해당 인터페이스 타입의 참조변수로 이를 구현한 클래스의 인스턴스를 참조할 수 있다.
- 인터페이스는 그것을 구현한 클래스의 부모라고 할 수 있다.
interface ILogger // 인터페이스
{
void WriteLog(string log);
}
class ConsoleLogger : ILogger // 인터페이스를 구현한 클래스
{
public void WriteLog(string log)
{
Console.WriteLine("{0} {1}", DateTime.Now.ToLocalTime(), log);
}
}
class Program
{
static void Main()
{
ILogger logger = new ConsoleLogger(); // 인터페이스를 이용한 다형성
}
}
출처
- 괭이쟁이
- bamsunbic의 기술 블로그
- C#이 보이는 그림책, 성안당
- 이것저것 개발 블로그
- 나의 지식 보관소
'SW Programming > C#' 카테고리의 다른 글
[Unity/C#] 상속과 클래스 구조 (0) | 2023.03.29 |
---|---|
배열과 리스트 (0) | 2022.07.04 |
[C#] 클래스와 구조체 (0) | 2022.06.01 |
[C#] 인터페이스와 추상 클래스, 추상 메소드와 가상 메소드에 대하여 (0) | 2022.05.12 |