01_클래스

Rio·2022년 2월 5일
0

C# 도감

목록 보기
2/3

✏️클래스 간 형식 변환

개와 고양이는 종은 다르지만 젖을 먹인다는 공통점 때문에 포유류로 분류된다.
이를 코드로 구현하면 다음과 같다.

//포유류 클래스
class Mammal{
	public void Nurse();
} 
//개 클래스
class Dog : Mammal{
	public void Bark();
}
//고양이 클래스
class Cat : Mammal{
	public void Meow();
}

그런데 포유류 = 포유류, 개 = 포유류, 고양이 = 포유류이므로 다음과 같이 작성 가능하다.

Mammal mamml = new Mammal();
mammal.Nurse();
mammal = new Dog();
mammal.Nurse();
Dog dog = (Dog)mammal;
dog.Nurse();
dog.Bark();
mamml = new Cat();
mammal.Nurse();
Cat cat = (Cat)mammal;
cat.Nurse();
cat.Meow();

이처럼 기반 클래스와 파생 클래스 사이에서 족보를 오르내리는 형식 변환이 가능하다.
파생클래스의 인스턴스는 기반 클래스의 인스턴스로서도 사용가능하다.
근데, 왜 이렇게 사용하지??
코드의 생산성이 높아진다.
예를 들어 Mammal클래스를 상속한 300개의 클래스가 파생되었다고 가정해보자.
그리고 동물원 사육사 클래스들 만들고 동물들을 씻기는 Wash() 메소드를 구현한다고 생각해보자.
그럼 300개의 Wash() 메소드를 오버로딩 해야한다

clas Zookeeper{
	public void Wash(Dog dog);
    public void Wash(Cat cat);
    public void Wash(Lion lion);
    // 등등 300개 Wash()메소드 선언
}

그러나 300개의 동물 클래스들이 모드 Mammal 클래스로부터 상속 받았기 때문에 이들은 모두 Mammal로 간주할 수 있다. 그래서 딱 하나의 Wash()메소드로 모든 동물 클래스에 적용이 가능하다

class Zookeeper{
	public void Wash(Mammal mammal);
}

✏️형식 변환 연산자_is_as

  • is
    객체가 해당 형식에 해당하는지 검사한 뒤 그 결과를 bool 값으로 반환한다.
Mammal mammal = new Dog();
Dog dog;
if(mammal is Dog){
	dog = (Dog)mammal;
    dog.Bark();
}
  • as
    형식 변환 연산자와 같은 역할을 한다. 다만 형식 변환 연산자가 변환에 실패하는 경우 예외를 throw하는 반면 as 연산자는 객체 참조를 null로 만든다는 것이 다르다.
Mammal mammal = new Cat();
Cat cat = mammal as Cat;
if(cat != null){ 
	cat.Meow();
}

일반적으로 (Dog)mammal이나 (Mammal)cat과 같이 형식 변환 대신 as 연산자를 사용하는 것을 권장한다. 형식 변환에 실패하더라도 예외가 일어나서 갑자기 코드의 실행이 점프(=catch구문으로 이동)하는 것을 막기에 코드를 관리하기가 더 수월하기 때문이다.
단, as 연산자는 참조 형식에 대해서만 사용이 가능하므로 값 형식의 객체는 기존의 형식 변환 연산자를 사용해야한다.

profile
우당탕탕 개발 기록지

0개의 댓글