NGMsoftware

NGMsoftware
로그인 회원가입
  • 매뉴얼
  • 학습
  • 매뉴얼

    학습


    C# 17-7. C# 상속한 배이스 클래스의 멤버 숨기기. (Hiding member of base class through inh…

    페이지 정보

    본문

    안녕하세요. 소심비형입니다. 이전 글에서 이미 디라이브 클래스에서 배이스 클래스의 맴버를 숨기기 위한 코드가 포함되어 있었습니다. 하지만, 이전 글에서는 상속에 대한 내용만을 전달하기 위해 다른 개념들은 설명하지 않고 넘어갔었습니다. 오늘 알아볼 내용은 상속을 통해 배이스 클래스의 멤버를 숨기는 방법입니다. C#의 상속된 메소드를 숨기는 기능은 C++의 상속된 멤버를 재정의하는 것과 비슷합니다.

     

    아래는 배이스 클래스의 맴버를 숨기는 간단한 예제입니다.

    using System;
     
    namespace MethodHiding
    {
        class Base
        {
            public void MyMethod()
            {
                Console.WriteLine("Base.MyMethod()");
            }
        }
     
        class Derived : Base
        {
            new public void MyMethod()
            {
                Console.WriteLine("Derived.MyMethod()");
            }
        }
     
        class MainApp
        {
            static void Main(string[] args)
            {
                Base baseObj = new Base();
                baseObj.MyMethod();
                Derived derivedObj = new Derived();
                derivedObj.MyMethod();
                Base baseOrDerived = new Derived();
                baseOrDerived.MyMethod();
            }
        }
    }

     

     

    위 15라인은 아래와 같이 접근 한정자 다음에 사용해도 됩니다.

            public new void MyMethod()

     

     

    new 한정자는 Derived 클래스의 MyMethod가 배이스 클래스의 멤버를 숨기는 새 메소드임을 나타냅니다. 이는 상속 관계에서 매우 유용한 기능이며, 배이스 클레스를 상속하여 기능을 수정할 때 사용합니다. 하지만, 가상 메소드와는 다른 개념이므로 혼동하면 안됩니다.

     

    아래 코드는 이전 글에서 사용한 예제입니다.

    using System;
    using System.Collections.Generic;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace ConsoleApplication1
    {
        class Inheritance { }
     
        enum Sex { 수컷, 암컷 }
     
        enum Species { 개과, 고양이과 }
     
        abstract class 동물
        {
            public Sex 성별 { get; set; }
            public Species 종 { get; set; }
            public string 이름 { get; set; }
            public abstract void 달리다(); public abstract void 짖다();
        }
     
        class 호랑이 : 동물
        {
            public Color 털색 = Color.Yellow; public Color 줄무늬색 = Color.Black; public override void 달리다() { }
            public override void 짖다()
            {
                Console.WriteLine("으르렁~");
            }
        }
     
        class 백호랑이 : 호랑이
        {
            public new Color 털색 = Color.White;
        }
     
        class 늑대 : 동물
        {
            public override void 달리다() { }
            public override void 짖다()
            {
                Console.WriteLine("아우~");
            }
        }
     
        abstract class 조류 : 동물 { }
     
        class 닭 : 조류
        {
            public Color 깃털색 = Color.White; public override void 달리다() { Console.WriteLine("두발로 달린다."); }
            public override void 짖다()
            {
                Console.WriteLine("꼬꼬댁~");
            }
        }
     
        class 병아리 : 닭
        {
            public new Color 깃털색 = Color.Yellow; public override void 짖다()
            {
                Console.WriteLine("삐약 삐약~");
            }
        }
    }

     

     

    위 코드의 51, 85라인과 같이 new로 배이스 클래스의 멤버를 숨기고 디라이브 클래스에서 같은 이름의 멤버를 만듭니다. 이 예제에서 확인 할수는 없지만, 가상 메소드의 경우 디라이브 클래스에서 override 키워드를 사용하여 다형성을 구현할 수 있습니다. 차이점은 기능을 확장할 수 있느냐 없느냐의 차이입니다. 가상 메소드와 오버라이드를 통해서만 기능을 확장할 수 있습니다.

     

    private 접근 한정자를 사용하여 새 멤버를 선언하면 새 멤버의 범위 내에서만 상속된 멤버가 숨겨집니다. C#에서 사용되는 접근 한정자중에서 public과 protected 멤버만 상속됩니다. public은 상속 관계가 아니더라도 모두 접근이 가능하며, protected는 상속 받은 디라이브 클래스에서만 접근이 가능합니다.

    class Base { public static void F() { } }
     
    class Derived : Base
    {
        // 디라이브 클래스의 범위에서만 멤버를 숨깁니다.        
        new private static void F() { }
    }
     
    class MoreDerived : Derived
    {
        // 배이스 클래스의 F 메소드 호출합니다.        
        static void G()
        {
            F();
        }
    }

     

     

    순차적으로 메소드를 호출합니다.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
     
    namespace ConsoleApplication1
    {
        class Program
        {
            static void Main()
            {
                Base.F();
                Derived.F();
                MoreDerived.F();
                MoreDerived.G();
                Console.ReadKey();
            }
        }
    }

     

     

    아래 결과와 같이 private 접근 한정자를 사용한 Derived 클래스의 맴버는 숨겨지고, 모두 Base의 맴버에 접근하는것을 알 수 있습니다.

    rSprREm.png

     

     

    배이스 클래스에서 너무 많은 기능을 제공하고 있을 때 이를 상속 받아서 구현된 파생 클래스에서 불필요한 기능을 제거해야 할 때 사용할 수 있습니다. BackgroundColor와 BackColor가 좋은 예가 될 수 있습니다. 같은 기능을 다른 이름으로 제공하는 경우는 흔히 볼 수 있습니다. 이런 것들은 사용자에게 혼란을 가중시키거나 일관성 없는 코드를 양산하게 됩니다.

     

    만약, 금융 상품이라고 할 때 Gold Membership은 3%의 할인 혜택이 있다고 생각해볼 수 있습니다. 물론, Gold Membership에서 파생된 상품들도 모두 3%의 혜택을 받을 수 있을겁니다. 하지만, 기업용 Gold Membership 상품을 개발하고 보니 일반인을 대상으로 하는 할인율을 적용할 수 없었습니다. 이 때는 Gold Membership의 할인 혜택을 숨기고 새로운 할인 혜택인 5%를 적용할 수 있어야 합니다. 또한, 일반인에게 제공되던 서비스는 기업에게 필요하지 않으므로 Membership의 서비스를 이용하여 제정의해야 합니다. 닭과 병아리가 다르게 짖다를 구현한 것처럼 말이죠.

     

    개발자에게 후원하기

    MGtdv7r.png

     

    추천, 구독, 홍보 꼭~ 부탁드립니다.

    여러분의 후원이 빠른 귀농을 가능하게 해줍니다~ 답답한 도시를 벗어나 귀농하고 싶은 개발자~

    감사합니다~

    • 네이버 공유하기
    • 페이스북 공유하기
    • 트위터 공유하기
    • 카카오스토리 공유하기
    추천0 비추천0

    댓글목록

    등록된 댓글이 없습니다.