객체지향의 4대 특성(1) : 추상화(2)

2. 클래스 멤버 vs 객체 멤버 = static 멤버 vs 인스턴스 멤버

객체는 유일무이하게 존재하는 실체이기 때문에 속성에 값을 가지고 있고, 클래스는 개념이면서 분류체계일 뿐이므로 속성에 값을 가질 수 없다. 그런데 다음과 같은 질문을 해보자.

  • 미키마우스의 꼬리는 몇 개인가?
  • 제리의 꼬리는 몇 개인가?
  • 쥐의 꼬리는 몇 개인가?

답은 모두 한 개이다. 꼬리 개수는 객체의 속성이지만 모든 객체가 같은 값을 가지고 있기 때문에 클래스를 통해 질문해도 하나라는 답을 알 수 있다.

이런 경우를 프로그램으로 작성한다고 가정하자. Mouse라는 클래스와 각각 Mickey, Jerry라는 클래스의 객체를 만들 수 있다. 그런데 모든 Mouse 객체가 꼬리 개수(CountOfTail)라는 속성에 모두 같은 값을 가지고 있음에도 불구하고 Mouse 객체 수 만큼 메모리를 낭비하고 있다. 이런 경우 한 곳에만 쥐의 꼬리 개수(CountOfTail)를 저장하고 싶어질 것이다. 따라서 같은 유형(클래스)의 모든 객체가 같은 값을 가지고 있다면 그 값을 클래스에 저장하는 것은 어떨까? 이런 공통 속성을 위해 Mouse.java의 코드는 static 키워드를 속성 앞에 붙여 다음과 같이 작성할 수 있다.

package abstraction;

public class Mouse {
    public String name;
    public int age;
    public static int countOfTail = 1;
    
    public void sing() {
        System.out.println(name + " 찍찍!!!");
    }
}

이제 countOfTail 속성은 T 메모리의 스태틱 영역에 단 하나의 저장 공간을 갖게 된다. countOfTail 속성에 접근하기 위해서는 객체를 이용해 객체참조변수.countOfTail로 접근하거나 클래스를 이용해 클래스명.countOfTail, 즉 Mouse.countOfTail로 접근할 수 있다. 이렇게 static 키워드가 붙은 속성을 클래스 멤버 속성이라고 한다. static이 안 붙은 속성은 객체 멤버 속성이라고 한다. 속성뿐만 아니라 메서드도 static 키워드를 붙였느냐 안 붙였느냐에 따라 클래스 멤버 메서드, 인스턴스 멤버 메서드로 분류한다. 클래스 멤버들은 static 키워드와 함께 사용되고 T 메모리의 static 영역에 상주하게 되므로 static(정적) 멤버라고도 한다. 객체 멤버들은 객체가 클래스의 인스턴스이므로 인스턴스 멤버라고도 한다.

따라서 정적 속성은 해당 클래스의 모든 객체가 같은 값을 가질 때 사용하는 것이 기본이다.

그럼 정적 메서드는 언제 사용하는 것이 좋을까? 정적 메서드는 객체들의 존재 여부에 관계없이 쓸 수 있는 메서드다. 일단 main() 메서드는 T 메모리가 초기화된 순간 객체가 존재하기 때문에 객체 멤버 메서드를 사용할 수 없으므로 당연히 정적 메서드여야 한다. 이러한 논리 외에도 정적 변수에 대한 접근자 메서드(getter)와 설정자(setter) 메서드로 사용하는 용도 정도가 있을 수 있다. 실무에서는 Math 클래스의 수많은 정적메서드와 같이 클래스의 인스턴스를 만들지 않고 사용하게 되는 유틸리티성 메서드를 주로 정적 메서드로 구성한다.

또한 정적 속성인 경우 T 메모리의 스태틱 영역에 클래스가 배치될 때 클래스 내부에 메모리 공간이 확보된다. 그러나 객체 속성은 속성명만 있지 실제 메모리 공간은 확보되지 않는다. 객체 속성은 힙 영역에 객체가 배치되면 바로 그때 각 객체 안에 멤버 속성을 위한 메모리 공간이 할당된다.

또한 지역 변수는 별도로 초기화해아 하나 클래스 속성과 객체 속성(멤버 변수)는 자동으로 초기화된다. 정수형은 0, 부동소수점형은 0.0, 논리형은 false, 객체는 null로 초기화된다.

참고

  • 스프링 입문을 위한 자바 객체지향의 원리와 이해

좋은 웹페이지 즐겨찾기