일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 | 29 | 30 |
Tags
- 포인터
- dart 언어
- jupyter
- c언어
- Algorithm
- C언어 포인터
- c# 추상 클래스
- c# 윈폼
- docker
- git
- c# winform
- jupyter lab
- Unity
- 유니티
- HTML
- 다트 언어
- Flutter
- Python
- gitlab
- 도커
- C# delegate
- 구조체
- 플러터
- Data Structure
- github
- Houdini
- vim
- 깃
- c#
- C++
Archives
- Today
- Total
nomad-programmer
[Programming/C#] 부모 클래스와 파생 클래스 사이의 형식 변환 (is, as) 본문
개와 고양이는 종은 다르지만 젖을 먹인다는 공통점이 있다. 그러기에 포유류로 분류된다. 이를 플래스로 다음과 같이 표현할 수 있다.
class Mammal
{
public void Nurse() {}
}
class Dog : Mammal
{
public void Bark() {}
}
class Cat : Mammal
{
public void Meow() {}
}
// /////////////////////////
Mammal mammal = new Dog();
mammal.Nurse();
Dog dog = (Dog)mammal;
mammal = new Cat();
mammal.Nurse();
위의 예처럼 부모 클래스와 파생 클래스 사이를 왔다 갔다 형식 변환이 가능하다. 파생 클래스의 인스턴스는 부모 클래스의 인스턴스로도 사용할 수 있다. 이렇게되면 코드의 생산성이 높아진다.
예를 들어 Mammal 클래스에서 300가지의 클래스가 파생되었다고 해보자. 그리고 동물원의 사육사 클래스를 만들고 이 동물들을 씻기는 Wash() 메소드를 구현한다고 생각해보자. 다음과 같이 300개의 Wash() 메소드를 오버로딩해야 한다.
class Zookeeper
{
public void Wash( Dog dog ) {}
public void Wash( Cat cat ) {}
public void Wash( Lion lion ) {}
public void Wash( Tiger tiger ) {}
.
.
.
// 등... 300개 버전의 Wash() 메소드 선언
}
하지만 300개의 동물 클래스가 모두 Mammal 클래스로부터 상속받았기 때문에 이들은 모두 Mammal로 간주할 수 있다.
따라서 다음과 같이 단 하나의 Wash() 메소드만 준비하면 300개의 동물 클래스에게 사용이 가능하다.
class Zookeeper
{
public void Wash( Mammal mammal ) {}
}
한편, C#은 형 변환을 위해 연산자 두 개를 제공한다. is와 as가 바로 그것이다.
연산자 | 설명 |
is | 객체가 해당 형식에 해당하는지를 검사하여 그 결과를 bool 값으로 반환한다. |
as | 형식 변환 연산자와 같은 역할을 한다. 다만 형 변환 연산자가 변환에 실패하는 경우 예외를 던지는 반면에 as 연산자는 객체 참조를 null로 만든다는 것이 다르다. |
is, as 사용 예
// is 연산자
Mammal mammal = new Dog();
Dog dog;
if (mammal is Dog)
{
// mammal 객체가 Dog형식임을 확인했으니 안전하게 형식 변환이 이뤄짐.
dog = (Dog)mammal;
dog.Bark();
}
// ///////////////////////////////////////
// as 연산자
Mammal mammal2 = new Cat();
Cat cat = mammal2 as Cat;
if (cat != null)
{
// mammal2가 Cat형식 변환에 실패하면 cat은 null이 된다.
// mammal2는 Cat형식이므로 안전하게 형식 변환이 이뤄짐.
cat.Meow();
}
일반적으로 형식 변환 연산자 대신 as 연산자를 사용하는 쪽이 권장된다 (빌 완그너가 지은 "Effective C#" 중).
형식 변환에 실패하더라도 예외가 일어나 갑자기 코드의 실행이 점프하는 일이 없으므로 코드 관리가 더 수월하다. 단, as 연산자는 참조 형식에 대해서만 사용이 가능하므로 값 형식의 객체는 기존의 형식 변환 연산자를 사용해야 한다.
using System;
using System.Globalization;
namespace CSharpExample
{
class Mammal
{
public void Nurse()
{
Console.WriteLine("Nurse()");
}
}
class Dog : Mammal
{
public void Bark()
{
Console.WriteLine("Bark()");
}
}
class Cat : Mammal
{
public void Meow()
{
Console.WriteLine("Meow()");
}
}
class MainApp
{
static int Main(string[] args)
{
Mammal mammal = new Dog();
Dog dog = null;
if (mammal is Dog)
{
dog = (Dog)mammal;
dog.Bark();
}
Mammal mammal2 = new Cat();
// Cat으로 형 변환이 실패하면 cat 참조 형식 변수에는 null이 들어감.
Cat cat = mammal2 as Cat;
if (cat != null)
cat.Meow();
Cat cat2 = mammal as Cat;
if (cat2 != null)
cat2.Meow();
else
Console.WriteLine("cat2 is not a Cat");
return 0;
}
}
}
/ * 결과
Bark()
Meow()
cat2 is not a Cat
*/
'Programming > C#' 카테고리의 다른 글
[Programming/C#] 오버라이딩과 다형성 (0) | 2020.09.09 |
---|---|
[Programming/C#] 추상 클래스 (0) | 2020.09.09 |
[Programming/C#] 상속 : base, base() (0) | 2020.09.08 |
[Programming/C#] 접근 한정자로 공개 수준 결정 (0) | 2020.09.08 |
[Programming/C#] this() 생성자 (0) | 2020.09.08 |
Comments