본문 바로가기
C#/책 정리

C# 정리 ) 상속

2021. 11. 28.

일상적인 많은 객체는 [계층적] 관계를 따른다.

데스크탑과 노트북을 생각해보자.

두 기기 모두 전원 종료와 이것저것, 컴퓨터의 기능을 한다.

하지만 노트북은 이동하며 사용할 수 있다는 기능이 추가된 것이다. 성능은 좀 떨어지지만 말이다.

다른 차이점들이야 물론 많지만 일단 이 차이점만 있다고 생각하자.

 

우리는 먼저 데스크탑부터 만들었다. 이제 노트북을 제작하려 한다.

기존 데스크탑을 노트북으로 개조하지는 않을 것이다.

노트북은 데트스탑에서 이동하며 사용하는 기능이 추가되어 있다.

 

이때 우리는 데스크탑을 한땀한땀 하나 더 만들고 노트북의 기능을 추가할 수도 있다.

하지만 데스크탑의 기능을 모두 가져와서 바로 노트북을 만들 수도 있다.

현실 물건으로 비유하니 좀 이상하지만 코드를 보면 확실히 머릿속에 정립이 될 것이다.

 

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Project1
{
    class desktop
    {
        bool power;
        public bool powerControl
        {
            get { return power; }
            set { power = value; }
        }
    }
    class netbook : desktop
    {
        bool isPortable = true;
        public bool isPort
        {
            get { return isPortable; }
        }
    }
    class Class1
    {
        public static void Main(String[] args)
        {
            netbook sam = new netbook();
            sam.powerControl = true;
            if (sam.isPort)
            {
                Console.WriteLine("sam 노트북은 휴대가 가능합니다");
            }
            else
            {
                Console.WriteLine("sam 노트북은 휴대가 불가능합니다");
            }
        }
    }
}

class netbook : desktop 부분은 netbook 클래스가 desktop의 기능을 가져온다는 것을 의미한다.

이를 상속이라 한다.

상속을 받은 클래스는 부모의 속성과 행위를 접근 제한자 규칙에 따라 외부에 제공한다.

 

Main 함수를 보면 netbook 클래스에 정의되지 않은 pwoerControl 메서드를 사용하는 것을 볼 수 있다.

powerControl은 상속을 제공하는 클래스 (부모클래스, 기반클래스, 슈퍼클래스 라고도 한다) 에 정의되어 있다.

슈퍼클래스를 상속받은 클래스 (자식클래스, 파생클래스, 서브클래스 라고도 한다) netbook이 이를 이용할 수 있다.

 

상속을 지정할 때에는 : 를 사용하여 지정한다.

JAVA의 경우 extends 를 이용하여 지정한다.

 

private 클래스 내부에서만 접근을 허용한다
protected 내부에서 접근과, 파생클래스에서만 접근을 허용한다.
public 내부 및 파생 클래스에서의 접근뿐만 아니라 외부에서도 접근을 허용한다.
internal 동일한 어셈블리 내에서 public에 준하는 접근을 허용한다.
internal protected 동일한 어셈블리 내에서 정의된 클래스 이거나 다른 어셈블리라면 파생 클래스인 경우에 한해 접근을 허용한다.

C# 접근지정자.

이를 통해 접근을 제한할 수 있다.

 

상속을 막는 방법 또한 있다.

sealed

sealed 를 사용하면 상속을 막아줄 수 있다.

많이 사용하는 string은 상속을 받지 못하는데, 이는 string 이 sealed 되어 있기 때문이다.

 

C#은 단일 상속만을 지원한다.

class notebook : computer, desktop

이런 식으로 한 번에 상속을 받을 수 없다는 소리이다.

 

여기 아래에서부터는 형변환 내용이 담겨있다.

상속 관련 내용만 보고 싶다면 이 아래는 안 보고 넘어가도 좋지만, 나중에 다시 와서 찾아보기를 바란다.


상속은 간단해 보이지만 이로 인해 파생되는 여러 가지 개념이 복잡하게 얽혀있다.

형변환을 생각해보자.

정수 안에 int가 있고, int 안에 short가 있다.

short a = 100;
int b = a;

short는 int 안에 별다른 작업 없이 들어갈 수 있다.

int의 범위가 short보다 넓고, 그 범위가 short의 범위를 포함하고 있기 때문이다.

이를 [암시적 형변환] 이라고 한다.

int c = 100;
short d = (short)c;

반대의 경우에는 (short)로 [명시적 형변환] 을 해주어야 한다.

이는 클래스의 상속에도 적용된다.

 

우리는 위에서 desktop과 netbook의 상속을 보았다.

desktop 안에 [특수화]된 netbook이 있는 것이다.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Project1
{
    class desktop
    {
        bool power;
        public bool powerControl
        {
            get { return power; }
            set { power = value; }
        }
    }
    class netbook : desktop
    {
        bool isPortable = true;
        public bool isPort
        {
            get { return isPortable; }
        }
    }
    class Class1
    {
        public static void Main(String[] args)
        {
            netbook net = new netbook();
            desktop desk = net;
            desk.powerControl = true;
        }
    }
}

netbook 객체를 desktop으로 바꿀 수는 있다.

netbook은 desktop에서 기능만 추가된 것이지 desktop의 기능을 모두 가지고 있는, 상속을 받은 클래스이기 때문이다.

하지만 이 반대는 오류가 생긴다. 물론 (netbook) 으로 [명시적 형변환] 을 해준다면 컴파일이 되기는 한다.

 

애초에 오류가 생기는데 이걸 굳이 안 막아 둔 이유가 있지 않을까? 하고 생각할 수 있다.

위험하게 동작할 수 있는 포인터는 새로운 언어가 나올 때마다 점점 숨어 들어가고 있지 않는가.

굳이 막지 않은 이유는 의도적으로 사용할 가능성이 있기 때문이다.

 

서브클래스를 슈퍼클래스로 바꾸고, 이를 다시 서브클래스로 바꿀 때 사용할 수 있다.

물론 [명시적 형변환] 보다는 [암시적 형변환] 이 많이 사용된다.

본인 또한 [명시적 형변환]을 사용해본 적이 많이 없다.

'C# > 책 정리' 카테고리의 다른 글

C# 정리 ) GetType  (0) 2021.11.28
C# 정리 ) ToString  (0) 2021.11.28
C# 정리 ) System.Object  (0) 2021.11.28
C# 정리 ) as, is 연산자  (0) 2021.11.28
C# 정리 ) 프로퍼티  (0) 2021.11.28

댓글