제로의영역

7.11 메소드 숨기기 본문

C#

7.11 메소드 숨기기

아이큐제로 2019. 6. 5. 16:31

* 본 블로그 글은 머리가 아~~~주 나쁜 왕X100초보가 프로그래밍을 공부하면서 정리를 위해 작성하는 글입니다. 잘못 정리되거나 제가 잘못 이해한 글은 이해 및 조언 부탁드립니다.

* 공부는 '이것이 C#이다' 책을 보고 하고 있습니다. 참고로 저같은 왕초보가 보기 어렵게 써져 있어서 별도의 정리 문서를 만들게 되었습니다.

 

 (1) 정의: CLR에게 부모 클래스에서 구현된 버전의 메소드를 감추고 자식 클래스에서 구현된 버전만을 보여주는 것

 ( 메소드를 감춘다니? 코드를 안보여준다는건가? 출력을 안시켜준다는건가? ㅡㅡ;; 인터넷을 뒤져보았습니다.) >> 재정의: 오버라이딩 되지 않은(virtual이 붙지 않은) 부모 클래스의 메소드를 무시하고 자식 클래스의 메소드에서만 같은 이름으로 재정의하여 사용하는 것. 코드 활용시 부모클래스의 메소드를 참고하지 않음

 

 (2) 용도: 재정의 되지 않은 부모 클래스를 변형하여 사용해야 할 경우 사용.

 

 (3) 사용법

  1) 자식 클래스의 메소드를 new 한정자로 수식(생성자의 new와 헷갈리지 말것)

  2) 한정자+new+반환형식+메소드 이름(변수) 또는 new+한정자+반환형식+메소드 이름(변수)

class Base
{
	public void MyMethod()
    {
    	Console.WriteLine("Base.MyMethod()");
    }
}

class Derived: Base
{
	public new void MyMethod()
    {
    	Console.WriteLine("Derived.MyMethod()"); /*Base.MyMethod()를 감추고 Derived 클래스에서
        MyMethod()만 노출. */
    }
}

 호출 예

Derived derived = new Derived();
derived.MyMethod();	//"Derived Method();" 출력

 override로 한정하지 않아도 자식 클래스의 메소드에서 부모 클래스의 메소드를 재정의해서 똑같은 결과를 얻을 수 있음.  

 

(4) 오버라이딩과 메소드 숨기기의 차이점

 메소드 숨기기는 메소드를 숨기고 있기만 하기 때문에 다음과 같이 객체를 선언하면 CLR에게 Base 버전의 MyMethod()가 노출 됨

Base baseOrDerived = new Derived();
baseOrDerived.MyMethod();	// "Base.MyMethod();" 출력!!

 이처럼 메소드 숨기기는 완전한 다형성을 표현하지 못함.

 따라서 기반 클래스를 설계할 때는 파생 클래스의 모습까지 고려해야 함.

 

예제)

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

namespace ex7_12
{
    class Mother
    {
        public void Mymethod()                      //부모클래스 메소드
        {
            Console.WriteLine("Mother.MyMethod()");
        }
    }

    class Child:Mother                              //부모클래스를 상속받은 자식클래스
    {
        public new void Mymethod()                  //부모클래스의 Mymethod()활용.virtual이 없으므로 new 사용
        {
            Console.WriteLine("Child.MyMethod()");
        }
    }
    class MainApp
    {
        static void Main(string[] args)
        {
            Mother baseObj = new Mother();          //부모클래스를 가리키는 baseObj생성
            baseObj.Mymethod();                     //부모클래스의 Mymethod()호출

            Child derivedObj = new Child();         //자식클래스를 가리키는 derivedObj생성
            derivedObj.Mymethod();                  //자식클래스의 Mymethod()호출

            Mother baseOrDerived = new Child();     //클래스와 생성자가 다름 
            baseOrDerived.Mymethod();               //오버라이딩이 아닐경우에만 숨은 부모클래스 메소드 노출. 오버라이딩일 경우 자식클래스 메소드 노출
        }
    }
}

 

출력결과:

Mother.MyMethod()
Child.MyMethod()
Mother.MyMethod()