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 메서드를 통해서만 접근합니다.
- 두 방식을 상황에 맞게 조합하면 데이터 공유와 보호를 동시에 실현할 수 있습니다.