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

C# 클래스와 정적 변수, 개념부터 예제까지 완벽 정리

C# 프로그래밍에서 정적(static) 변수는 클래스의 인스턴스를 생성하지 않고도 클래스 이름만으로 접근할 수 있는 특별한 멤버 변수입니다. 이러한 특성 때문에 정적 변수는 주로 상수를 정의하거나 여러 객체가 공유해야 하는 값을 저장할 때 사용됩니다.

정적 변수(Static Variable)의 특징

정적 변수는 인스턴스를 만들지 않고 클래스를 직접 호출해 값을 읽어올 수 있습니다. 또한 멤버 함수나 클래스 정의 외부에서 초기화할 수 있으며, 필요하다면 클래스 정의 내부에서 초기화하는 것도 가능합니다.

  • 공유 메모리: 같은 클래스의 모든 인스턴스가 하나의 변수를 함께 사용합니다.
  • 인스턴스 불필요: new 키워드 없이 클래스명으로 바로 접근할 수 있습니다.
  • 상수 정의에 적합: 변하지 않는 값이나 전역적으로 사용되는 데이터를 담기 좋습니다.

정적 변수 예제

아래 예제는 서로 다른 두 객체(s1, s2)가 동일한 정적 변수 num을 공유하는 모습을 보여줍니다.

using System;

namespace StaticVarApplication {
    class StaticVar {
        public static int num;

        public void count() {
            num++;
        }
        public int getNum() {
            return num;
        }
    }
    class StaticTester {
        static void Main(string[] args) {
            StaticVar s1 = new StaticVar();
            StaticVar s2 = new StaticVar();

            s1.count();
            s1.count();
            s1.count();

            s2.count();
            s2.count();
            s2.count();

            Console.WriteLine("Variable num for s1: {0}", s1.getNum());
            Console.WriteLine("Variable num for s2: {0}", s2.getNum());
            Console.ReadKey();
        }
    }
}

위 코드에서 각 객체마다 세 번씩 count() 메서드를 호출했는데, 두 객체 모두 6이라는 결과가 출력됩니다. 그 이유는 정적 변수 num이 객체마다 별도로 존재하는 것이 아니라 클래스 차원에서 하나만 존재하며, 모든 인스턴스가 이 값을 함께 공유하기 때문입니다.

실행 결과

Variable num for s1: 6
Variable num for s2: 6

클래스 변수와 캡슐화

설계 관점에서 클래스 변수는 객체의 속성(attribute)에 해당합니다. 이러한 변수들은 캡슐화(encapsulation)를 구현하기 위해 일반적으로 private으로 선언되며, 외부에서는 public 멤버 함수를 통해서만 접근할 수 있습니다.

캡슐화를 적용하면 내부 데이터를 외부로부터 보호할 수 있고, 검증되지 않은 값이 직접 할당되는 것을 막아 객체의 상태를 안전하게 유지할 수 있습니다.

클래스 변수 예제

아래 예제는 박스(Box) 클래스의 길이·너비·높이를 private 필드로 선언하고, setter 메서드를 통해 값을 설정한 뒤 부피를 계산하는 코드입니다.

using System;

namespace BoxApplication {
    class Box {
        private double length;   // 상자의 길이
        private double breadth;  // 상자의 너비
        private double height;   // 상자의 높이

        public void setLength(double len) {
            length = len;
        }
        public void setBreadth(double bre) {
            breadth = bre;
        }
        public void setHeight(double hei) {
            height = hei;
        }
        public double getVolume() {
            return length * breadth * height;
        }
    }
    class Boxtester {
        static void Main(string[] args) {
            Box Box1 = new Box();  // Box 타입의 Box1 선언
            Box Box2 = new Box();  // Box 타입의 Box2 선언
            double volume;

            // 첫 번째 상자 크기 설정
            Box1.setLength(6.0);
            Box1.setBreadth(7.0);
            Box1.setHeight(5.0);

            // 두 번째 상자 크기 설정
            Box2.setLength(12.0);
            Box2.setBreadth(13.0);
            Box2.setHeight(10.0);

            // 첫 번째 상자 부피 계산
            volume = Box1.getVolume();
            Console.WriteLine("Volume of Box1 : {0}", volume);

            // 두 번째 상자 부피 계산
            volume = Box2.getVolume();
            Console.WriteLine("Volume of Box2 : {0}", volume);
            Console.ReadKey();
        }
    }
}

private 필드에는 setter 메서드를 통해서만 접근할 수 있으므로, 객체의 데이터가 안전하게 보호됩니다. 결과적으로 Box1은 6 × 7 × 5 = 210, Box2는 12 × 13 × 10 = 1560의 부피가 출력됩니다.

실행 결과

Volume of Box1 : 210
Volume of Box2 : 1560

정리

  • 정적 변수는 인스턴스 생성 없이 클래스 이름으로 접근하며, 모든 객체가 값을 공유합니다.
  • 일반 클래스 변수는 캡슐화를 위해 private으로 선언하고 public 메서드를 통해서만 접근합니다.
  • 두 방식을 상황에 맞게 조합하면 데이터 공유와 보호를 동시에 실현할 수 있습니다.