티스토리 뷰
클래스는 다른 클래스로부터 필드나 메소드, 프로퍼티 같은 멤버들을 물려 받을 수 있습니다.
객체 지향 프로그래밍에서는 물려받는 클래스(파생or자식 클래스)가 유산을 물려줄 클래스(기반or부모 클래스)를 지정
다음 코드가 상속의 예이다.
class Base()
{
public void BaseMethod()
{
Console.WriteLine("BaseMethod");
}
}
class Derived : Base
{
}
파생 클래스는 자신만의 고유한 멤버 외에도 기반 클래스로부터 물려받은 멤버를 가지고 있다.
이것은 바로 파생 클래스가 기반 클래스 위에 새로운 멤버를 얹어서 만든 것이기 때문이다.
파생 클래스는 객체를 생성할 때 내부적으로 기반 클래스의 생성자를 호출한 후에 자신의 생성자를 호출하고
객체가 소멸될 때는 반대로 파생클래스의 소멸자부터 기반 클래스의 소멸자를 호출한다.
class Base
{
public Base()
{
Console.WriteLine("Base()");
}
~Base()
{
Console.WriteLine("~Base()");
}
}
class Derived : Base
{
public Derived()
{
Console.WriteLine("Derived()");
}
~Derived()
{
Console.WriteLine("~Derived()");
}
}
class MainApp{
static void Main(string[] args)
{
Derived derived = new Derived();
}
}
///result
/*
Base()
Derived()
~Derived()
~Base()
*/
위 코드의 결과처럼 기반 클래스의 생성자-> 파생 클래스의 생성자 -> 파생 클래스의 소멸자 -> 기반 클래스의 소멸자
순으로 호출이 된다.
그러면 기반 클래스의 생성자에 매개변수를 넣어줘야 하는 상황이면 파생 클래스는 어떻게 기반 클래스의 생성자에
접근을 할 수 있을까? 아래와 같이 접근을 하면 된다.
class Base()
{
protected string Name;
public Base(string Name)
{
this.Name = Name;
}
}
//첫번째 방법
class Derived : Base
{
public Derived(string Name) : base(Name)
{
}
}
파생 클래스에서 기반 클래스의 메소드를 호출하는 방법은 아래와 같다.
class Derived : Base
{
public void DerivedMethod()
{
base.BaseMethod();
}
}
seald 한정자
의도하지 않은 상속이나 파생 클래스의 구현을 막기 위해 상속이 불가능하도록 클래스를 선언하는 것이다.
seald class Base
{
}
이렇게 작성하면 된다. 이런 클래스를 봉인 클래스라고도 부른다.
형변환
파생 클래스의 인스턴스는 기반 클래스의 인스턴스로도 사용할 수 있다.
코드로 다음과 같이 작성할 수 있다.
class Mammal
{
public void Nurse() { }
}
class Dog : Mammal
{
public void Bark() { }
}
class Cat : Mammal
{
public void Meow() { }
}
//Main에서 작성
Mammal mammal = new Mammal();
mammal = new Dog();
mammal.Nurse();
Dog dog = (Dog)mammal;
dog.Nurse();
dog.Bark();
mammal = new Cat();
mammal.Nurse();
Cat cat = (Cat)mammal;
cat.Nurse();
cat.Meow();
기반클래스와 파생 클래스의 형변환을 통해 코드의 생산성을 높일 수 있다.
예를 들어 Mammal 클래스에서 300가지의 클래스가 파생되었다고 가정하고
사육사 클래스를 만들어 이 동물들을 씻기는 Wash() 메소드를 구현했다고 가정한다.
class ZooKeeper
{
public void Wash(Dog dog) { }
public void Wash(Cat cat) { }
public void Wash(Lion lion) { }
.
.
.
}
이렇게 300종류의 동물들을 씻기는 Wash메소드를 오버로딩하는 것 보다
Mammal 클래스 하나만 씻기는 Wash메소드를 만들면 모든 동물 클래스에서 사용이 가능해진다.
class Zookeeper
{
public void Wash(Mammal mammal) { }
}
C#에서는 이 형변환을 위해 연산자 두 개를 제공한다.
연산자 | 설명 |
is | 객체가 해당 형식에 해당하는지 검사해 결과를 bool 값으로 반환한다 |
as | 형변환 연산자와 같은 역할. 다만 변환에 실패한 경우 객체 참조를 null로 만든다 |
//is 연산자 사용
Mammal mammal = new Dog();
Dog dog;
if(mammal is Dog)
{
dog = (Dog)mammal;
dog.Bark();
}
//as 연산자 사용
Mammal mammal2 = new Cat();
Cat cat = mammal2 as Cat;
if(cat != null) //형변환에 실패하는 경우에 cat은 null이 된다.
{
cat.Meow();
}
일반적으로 형식 변환 연산자 대신에 as 연산자를 사용하는 쪽이 권장된다.
왜냐면 형 변환에 실패하더라도 예외가 일어나 갑자기 코드의 실행이 점프하는 일이 없으므로 관리하기가
더 수월하기 때문이다. 단 as 연산자는 참조 형식에 대해서만 사용가능
'C#' 카테고리의 다른 글
5. 구조체 (0) | 2020.01.29 |
---|---|
4. 클래스(4) - 오버라이딩 (0) | 2020.01.29 |
4. 클래스(2) - 정적필드, this 키워드, 접근 한정자 (0) | 2020.01.28 |
4. 클래스(1) - 클래스란? , 생성자와 소멸자 (0) | 2020.01.28 |
3. 메소드란? (0) | 2020.01.28 |
- Total
- Today
- Yesterday
- visual studio code
- C언어
- 언리얼엔진
- css
- 차이점
- 동영상을
- 객체
- 안드로이드 스튜디오
- 관계형데이터베이스
- HTML
- php
- 생활코딩
- 생활코딩#MySQL
- inline
- 변수
- 알고리즘
- 네트워크 프로그래밍
- 정렬
- 선택자
- 글로
- 기초
- Link
- 언리얼엔진4
- GRID
- 조건문
- TAG
- 문자열
- javascript
- PHP&MySQL
- 생활코딩#동영상을#글로#html
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | ||||||
2 | 3 | 4 | 5 | 6 | 7 | 8 |
9 | 10 | 11 | 12 | 13 | 14 | 15 |
16 | 17 | 18 | 19 | 20 | 21 | 22 |
23 | 24 | 25 | 26 | 27 | 28 |