본문 바로가기

취미로 하는 게임코딩_gameCodingAsHobby/유니티unity로 게임 만들기

유니티35_C#_20_static 스태틱

static (스태틱; 정적인, 고정된)

static은 객체를 생성하지 않고도 멤버에 접근할 수 있게 만드는 키워드이다.

class(클래스), field(필드), method(메서드) 등에 붙여서 static 멤버로 만들 수 있다.

 

정상적인 방법으로 클래스의 필드(변수)에 접근하는 예는 아래와 같다.

 

TestClass에 number라는 필드(변수)가 정의되어 있다.

이 필드에 접근하려면 TestClass 타입의 변수(testObject)를 정의하고 new키워드로 새 객체를 만들어 저장한다.

그리고 객체를 가진 이 변수를 통해서 number에 접근해서 다른 값을 입력할 수 있다.

 

이번에는 필드(number)를 static으로 지정하면 다음과 같이 접근할 수 있다.

 

필드(변수)를 static으로 지정하면 '클래스명.필드명' 으로 필드에 바로 접근할 수 있다.

 

메서드 또한 static으로 지정하면 '클래스명.메서드명' 으로 해당 메서드를 호출할 수 있다.

 

결국 static으로 선언한 멤버는 객체와는 상관없는 클래스 자체의 고정 멤버가 된다.

그러므로 static 멤버는 반드시 클래스명과 함께 호출해야 하고 인스턴스(객체)를 생성해서 호출할 수 없다.

또한 static으로 선언한 클래스는 인스턴스(객체)를 만들 수 없다.

 

static 사용

C#, Java, Python 등 요즘 대중적인 많은 언어들이 객체를 지향하는 OOP (Object Oriented Programming) 언어들이다.

그런데 static 은 객체 지향과는 반대의 개념으로 접근한다.

 

위 예에서 보듯이 static을 사용하지 않아도 코드만 조금 길어질 뿐 사용에는 아무런 문제가 없다.

그런데 왜 객체지향에 역행하는 static을 만들었을까?

 

static(정적인, 고정된)은 그 뜻이 의미하는 바와 같이 '변하지 않는' 그리고 '인스턴스(객체)와 상관없는' 필드나 매서드에 사용할 수 있다.

 

예를 살펴보면서 어떤 경우에 사용하는 지 확인해보자.

 

static field(필드)

 

먼저 static 필드의 사용에 대해 알아본다.

 

 

15번줄에 User(사용자)라는 클래스가 있다.

id, pasword, numberOfUsers라는 필드(변수)가 있다.

 

21번줄에 아이디와 패스워드를 받는 생성자가 호출되면 사용자가 몇 명 들어왔는지 알기 위해 numberOfUsers (사용자 수)라는 필드를 만들어 생성자에서 ++ 기호로 값을 1씩 증가시킨다고 생각해보자.

 

7~9번 줄에 사용자가 3명 들어왔다고 가정하고 user3까지 객체를 생성해보자.

인스턴스(객체) user3으로 numberOfUsers필드에 접근해서 값을 출력하면 다음과 같이 나타난다.

 

 

3 이어야 하는데 1이다.

 

이렇게 되는 이유는 객체가 생성될 때 마다 numberOfUsers 필드는 초기화 되어 0이 된 후 1 증가하기 때문에 user1 , user2, user3 모두 numberOfUsers값은 1이 된다.

 

그러므로 여기에서 numberOfUsers필드의 역할은 사용자가 생길 때 마다 1씩 증가해야 하므로 이 필드는 처음 초기화 될 때 '고정(static)' 될 필요가 있다. 실제로 static으로 지정하면 User클래스가 처음 호출될 때 한번만 초기화 되어 메모리에 0 이 저장되고 그 후 계속 같은(고정된) 메모리를 사용하면서 값을 유지한다.

 

다음과 같이 수정한 후 출력해보자.

 

 

static Method(메서드)

 

이번에는 static 메서드에 대한 예를 알아본다.

static 메서드의 단적인 예는 유니티에서 사용하는 Debug.Log( ) 메서드이다.

이 메서드는 Console(콘솔)창에 메세지를 출력하는 용도로 사용한다.

그런데 콘솔창에는 한번에 하나만 실행할 수 있으므로 매번 사용할 때 마다 인스턴스(객체)를 만드는 것은 의미가 없다.

그래서 유니티 엔진의 Debug클래스에 Log( )메서드를 static으로 지정해 두고 Debug.Log( )로 바로 호출할 수 있도록 한 것이다.

 

 

또한 앞 글 String문자열 에서 사용한 String.Format( )메서드 역시 static으로 선언된 메서드이다.

즉, String클래스에 Format( )를 static 으로 지정해서 클래스명으로 바로 호출해서 사용했다.

 

반면에 IndexOf( ), Replace( ), Split( ), Substring( )메서드는 static이 아니므로 객체를 이용해서 접근했다.

 

Format( )메서드를 static으로 선언한 이유는 이 메서드의 기능을 보면 알 수 있다.

호출하여 표시만 하면 되는 단순한 기능이고 자주 사용하기 때문인 것 같다.

 

한가지 더 예를 들면 수학에 관련된 클래스 안에 어떤 기능을 하는 메서드를 만든다고 가정한다.

어떤 값을 전달하면 반올림 하여 반환하는 것과 같은 간단한 기능의 메서드인 경우에도 매번 객체를 만드는 것 보다 static 메서드로 만들면 즉시 접근할 수 있기 때문에 유용할 것이다. 이미 앞 글 '문자열'에서 string.Format()에 자동 반올림 기능의 예를 보았다.

 

static class(클래스)

 

클래스를 static으로 선언하면 다음과 같은 규칙에 따라야 한다.

 

  1. static클래스는 객체를 생성할 수 없다.
  2. static클래스의 모든 멤버는 static 이어야 한다.
  3. static클래스는 상속될 수 없다.
  4. static클래스는 프로그램이 끝날 때 까지 메모리에 남아있다.
  5. static클래스 멤버에 접근하려면 클래스명.멤버명을 사용한다.

 

결론적으로 static을 사용할 때는 신중해야 하며, 자신이 왜 static을 붙이는 지 확실히 모르는 상태에서는 사용하지 않는 것이 좋다고 한다.

 

끝.

Wraven...