전체 코드

using System.ComponentModel;
using System.Numerics;
using System.Threading;

namespace CSharp
{

    // 은닉성

    // ex)
    // 자동차
    // - 전기장치
    // - 엔진
    // - 등등의 기술들을 사용자들에게 노출 시키는 것은 문제가 될 이유가 있음
    // 따라서 은닉할 필요가 있다.
    // 
    // 이러한 예가 은닉성에 대한 예

    class Knight
    {
        //private int hp;
        protected int hp;

        public void SceretFunction()
        {

        }



        // why 필요하냐
        // 프로그래밍이 커지면 다른 사람과 작업함
        // 어떠한 기능이 절대 사용하지 않아야 할경우 노출을 시켜버리면
        // 사용해서 프로그램을 이상하게 만들 가능성이 있음
        // 이러한 경우에 대비해서 보안 레벨을 가져야할 필요하 있다.

        // 접근 한정자
        // public - 누구나 사용가능
        // protected - 상속 받은 자식클래스에서 사용가능
        // private - 자신만 사용 가능
        // why SetHp 로 사용
        // 장점이 있음 - SetHP로 사용하면 바로 함수를 찾아서 호출 스택을 보고 접근을 바로 찾을 수 있다.

        // 접근 한정자를 붙이지 않으면 private으로 동작한다.
        public void SetHp(int hp)
        {
            this.hp = hp;
        }
    }
    class SuperKight : Knight
    {

        void Test()
        {
            hp = 10; // 사용가능
        }
        
    }
    internal class Program
    {
        
        static void Main(string[] args)
        {
                Knight knight = new Knight();


        }

    }
}

1. 은닉성(Encapsulation)이란?

은닉성(Encapsulation)은 객체 지향 프로그래밍(OOP)의 핵심 개념 중 하나로, 객체의 내부 상태를 외부로부터 보호하고, 접근을 제한하는 방식을 의미합니다.
이를 통해 다음과 같은 장점을 얻을 수 있습니다:

  • 데이터 보호: 외부에서 직접 접근할 수 없도록 하여, 객체의 무결성을 유지할 수 있습니다.
  • 유지보수 용이성: 특정 데이터를 변경해야 할 때, 외부 코드에 영향을 주지 않고 내부 로직만 수정할 수 있습니다.
  • 안전성 증가: 잘못된 값이 직접 할당되는 것을 방지하고, 검증 로직을 추가할 수 있습니다.

2. 접근 한정자(Access Modifiers)

C#에서는 멤버 변수와 메서드의 접근 범위를 결정하기 위해 접근 한정자를 사용합니다.

접근 한정자설명
public외부에서 자유롭게 접근 가능. 클래스의 외부에서도 호출할 수 있음.
private선언된 클래스 내부에서만 접근 가능. (디폴트 값)
protected외부에서는 접근할 수 없지만, 상속받은 자식 클래스에서는 접근 가능.

🔥 중요!

  • private 멤버는 외부에서 직접 접근할 수 없습니다. 이를 해결하기 위해 getter, setter 메서드를 활용하여 안전하게 접근할 수 있도록 합니다.
  • protected는 상속을 고려한 접근 한정자로, 부모-자식 클래스 간의 데이터 공유가 가능하지만 외부 클래스에서는 접근할 수 없습니다.

3. 코드 분석 - 은닉성 중심

다음은 Knight 클래스를 활용하여 은닉성을 설명하는 코드입니다.

Knight 클래스 - 데이터 보호 및 접근 제어

class Knight
{
    // 1️⃣ private 필드 - 클래스 내부에서만 접근 가능
    private int level;
    
    // 2️⃣ protected 필드 - 상속받은 클래스에서 접근 가능
    protected int hp;
    
    // 3️⃣ public 메서드 - 외부에서 접근 가능, hp 값을 설정하는 기능 제공
    public void SetHp(int hp)
    {
        this.hp = hp; // 외부에서 직접 접근은 불가능하지만, public 메서드를 통해 변경 가능
    }
    
    // 4️⃣ private 메서드 - 외부에서는 호출할 수 없음
    private void SecretFunction()
    {
        hp = 20; // 내부 로직에서만 값 변경 가능
    }
}

🧐 코드 분석

  • private int level;level은 외부에서 접근할 수 없음 (오직 Knight 클래스 내부에서만 사용 가능).
  • protected int hp;hp는 외부에서는 접근 불가능하지만, 상속받은 클래스에서는 접근 가능.
  • public void SetHp(int hp);public 메서드를 통해 hp 값을 안전하게 변경할 수 있음.
  • private void SecretFunction();외부에서는 호출할 수 없는 비공개 기능.

4. SuperKnight 클래스 - 상속과 보호된 데이터 접근

class SuperKnight : Knight
{
    void Test()
    {
        hp = 10; // ✅ 상속받은 클래스에서는 protected 멤버에 접근 가능
    }
}

🧐 코드 분석

  • SuperKnight 클래스는 Knight 클래스를 상속받은 자식 클래스.
  • hp = 10; → 부모 클래스의 protected 멤버는 상속받은 클래스에서 접근 가능.
  • level에는 접근할 수 없음 (levelprivate으로 선언되어 있기 때문).

5. Main 메서드에서 객체 생성 및 사용

class Program
{
    static void Main(string[] args)
    {
        Knight knight = new Knight();

        // knight.hp = 1; ❌ 오류 발생! `hp`는 `protected`이므로 외부에서 직접 접근 불가능
        
        knight.SetHp(10); // ✅ `public` 메서드를 통해 `hp` 값을 안전하게 변경 가능
    }
}

🧐 코드 분석

  • knight.hp = 1;오류 발생 (외부에서 protected 멤버에 접근할 수 없음).
  • knight.SetHp(10);public 메서드를 통해 hp 값을 변경하는 방식이 올바름.

6. 접근 한정자 사용 이유 & Getter/Setter의 중요성

❌ 만약 hppublic이라면?

class Knight
{
    public int hp;
}
knight.hp = -100; // ❌ 비정상적인 값이 들어가도 차단할 방법이 없음

✅ Getter & Setter를 활용한 안전한 접근

class Knight
{
    private int hp;
    
    public void SetHp(int value)
    {
        if (value < 0)
        {
            Console.WriteLine("HP는 0보다 작을 수 없습니다!");
            return;
        }
        hp = value;
    }
    
    public int GetHp()
    {
        return hp;
    }
}
Knight knight = new Knight();
knight.SetHp(-100); // 🚨 "HP는 0보다 작을 수 없습니다!" 출력

📌 요점: private로 멤버를 보호하고, public 메서드로 검증을 거쳐 값이 설정되도록 해야 함.


7. 은닉성이 중요한 이유

  1. 데이터 보호 - 외부에서 임의로 변경하지 못하도록 차단.
  2. 유지보수 용이 - 내부 로직을 수정해도 외부 코드에는 영향이 없음.
  3. 버그 방지 - 불필요한 직접 접근을 차단하여 코드의 안정성을 높임.
  4. 디버깅 편의성 - setter를 활용하면 어디서 값이 변경되었는지 추적 가능.

🔥 은닉성의 핵심은 '보호'와 '제어'입니다. 필요한 부분만 외부에 노출하고, 객체 내부 상태는 안전하게 유지하는 것이 중요합니다.


profile
李家네_공부방

0개의 댓글