Computer >> 컴퓨터 >  >> 프로그래밍 >> C#

C# public, protected, private 접근 지정자 차이점 완벽 정리

C#에서 접근 지정자(Access Specifier)는 클래스의 멤버 변수와 멤버 함수에 대한 외부 접근 범위를 결정하는 핵심 요소입니다. 적절한 접근 지정자를 사용하면 캡슐화를 구현하고 코드의 안정성과 유지보수성을 높일 수 있습니다. 이번 글에서는 가장 많이 사용되는 세 가지 접근 지정자인 public, protected, private의 차이점을 예제 코드와 함께 자세히 살펴보겠습니다.

1. Public 접근 지정자

public은 가장 개방적인 접근 수준으로, 클래스가 자신의 멤버 변수와 멤버 함수를 다른 함수 및 객체에 공개하도록 허용합니다. 즉, 모든 public 멤버는 클래스 외부 어디에서든 자유롭게 접근할 수 있습니다.

예제 코드

using System;
namespace Demo {
    class Rectangle {
        public double length;
        public double width;
        public double GetArea() {
            return length * width;
        }
        public void Display() {
            Console.WriteLine("Length: {0}", length);
            Console.WriteLine("Width: {0}", width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    } //end class Rectangle
    class ExecuteRectangle {
        static void Main(string[] args) {
            Rectangle r = new Rectangle();
            r.length = 7;   // 클래스 외부에서 직접 접근 가능
            r.width = 10;
            r.Display();
            Console.ReadLine();
        }
    }
}

실행 결과

Length: 7
Width: 10
Area: 70

위 예제에서 lengthwidth 필드가 public으로 선언되었기 때문에, Main 메서드에서 객체 r를 통해 직접 값을 할당할 수 있었습니다. 편리하지만, 외부에서 내부 상태를 마음대로 변경할 수 있다는 점에서 데이터 무결성 측면에는 주의가 필요합니다.

2. Protected 접근 지정자

protected상속 관계에서만 접근을 허용하는 접근 수준입니다. 기본(부모) 클래스의 protected 멤버는 해당 클래스 자신과 이를 상속받은 파생(자식) 클래스 내부에서만 접근할 수 있으며, 클래스 외부에서는 접근할 수 없습니다.

다음은 protected 멤버에 접근하는 방법을 보여주는 예제입니다.

예제 코드

using System;
namespace MySpecifiers {
    class Demo {
        protected string name = "Website";
        protected void Display(string str) {
            Console.WriteLine("Tabs: " + str);
        }
    }
    class Test : Demo {   // Demo 클래스를 상속
        static void Main(string[] args) {
            Test t = new Test();
            // 상속받은 protected 멤버에 접근
            Console.WriteLine("Details: " + t.name);
            t.Display("Product");
            t.Display("Services");
            t.Display("Tools");
            t.Display("Plugins");
        }
    }
}

실행 결과

Details: Website
Tabs: Product
Tabs: Services
Tabs: Tools
Tabs: Plugins

Test 클래스는 Demo 클래스를 상속했기 때문에 부모 클래스의 protected 멤버인 name 필드와 Display() 메서드에 접근할 수 있습니다. 만약 상속 관계가 없는 외부 코드에서 접근하려고 하면 컴파일 오류가 발생합니다.

3. Private 접근 지정자

private는 가장 제한적인 접근 수준입니다. private로 선언된 멤버는 같은 클래스 내부의 멤버 함수만 접근할 수 있으며, 다른 클래스나 객체는 물론, 해당 클래스의 인스턴스를 통해서도 외부에서 접근할 수 없습니다. 참고로 클래스 멤버에 접근 지정자를 명시하지 않으면 기본값으로 private가 적용됩니다.

예제 코드

using System;
namespace Demo {
    class Rectangle {
        // 멤버 변수 - private 선언
        private double length;
        private double width;
        // public 메서드를 통해서만 private 멤버에 접근
        public void Acceptdetails() {
            length = 10;
            width = 15;
        }
        public double GetArea() {
            return length * width;
        }
        public void Display() {
            Console.WriteLine("Length: {0}", length);
            Console.WriteLine("Width: {0}", width);
            Console.WriteLine("Area: {0}", GetArea());
        }
    } //end class Rectangle
    class ExecuteRectangle {
        static void Main(string[] args) {
            Rectangle r = new Rectangle();
            // r.length = 10;  ← 컴파일 오류! private 멤버는 외부 접근 불가
            r.Acceptdetails();
            r.Display();
            Console.ReadLine();
        }
    }
}

실행 결과

Length: 10
Width: 15
Area: 150

이 예제에서 lengthwidth는 private이므로 외부에서 직접 수정할 수 없고, 오직 클래스 내부의 public 메서드인 Acceptdetails()를 통해서만 값이 설정됩니다. 이처럼 private 멤버와 public 메서드를 조합하면 캡슐화(Encapsulation)를 효과적으로 구현할 수 있습니다.

세 가지 접근 지정자 비교 요약

접근 지정자같은 클래스 내파생 클래스(상속)클래스 외부
publicOOO
protectedOOX
privateOXX

마무리

접근 지정자 선택은 단순한 문법 문제가 아니라 설계 철학의 문제입니다. 일반적으로 다음 원칙을 따르는 것이 좋습니다.

  • private: 내부 구현 세부사항은 최대한 숨기고, 필요한 경우에만 공개합니다.
  • protected: 상속 계층에서 자식 클래스가 활용해야 하는 멤버에 사용합니다.
  • public: 외부에 제공해야 하는 인터페이스(API)에만 신중하게 사용합니다.

이 세 가지 접근 지정자를 상황에 맞게 적절히 활용하면 안전하고 유지보수하기 쉬운 C# 프로그램을 작성할 수 있습니다.