반응형

이전시간에 , 선언 위치에 따라서 변수의 종류가 달라질 수 있다고 했다.

클래스 영역에 선언된 변수인 iv와 cv이 둘의 차이점에 대해서 알아보도록 하겠다.

 


 

클래스 변수와 인스턴스 변수

예를 들어서 이렇게 포커카드가 있다고 했을 때,
이 카드의 속성은 뭐가 있을까?

숫자, 무늬 폭, 높이 등의 속성이 있다.

그리고 카드하나하나가 card객체이다.

그리고 card객체마다 숫자, 무늬는 개별값이다. 
즉, 숫자 무늬같은 개별값은 객체마다 다르게 유지되어야 하는 값이다.

그리고 폭하고 높이는 모든 card객체가 공통적으로 가져야 하는 값이다.


그래서 모두 같은 속성일지라도,
무늬와 숫자속성은 개별속성,
폭과 높이는 공통속성이다.

객체마다 다르게 유지되어야 하는 속성은 개별속성 이고, iv(인스턴스변수)로 나타내고,
모든객체가 동일하게 유지되야 하는 속성은 공통속성이고, cv(static + iv)로 나타낸다.

 

Card클래스가 이렇게 정의되어 있을 때, kind와 number속성은 iv(개별 속성)이고,
width, height는 iv에 static이 붙은 형태이므로 cv(공통 속성)이다.

이제 이 클래스를 사용해보자.

Card c = new Card();	// 객체 생성
c.kind = "HEART";		// iv 사용
c.number = 5;			// iv 사용
c.width = 200;			// cv 사용
c.height = 300;			// cv 사용

iv하고 cv의 사용법이 같은데,
cv같은 경우, 이렇게 사용하면 가능은 하지만 권장하는 방법은 아니다.

사실 cv는 아래와 같이 사용해야 한다.

Card.width = 200;
Card.height = 300;

cv는 앞에 참조변수 대신, 클래스명붙어야 한다.

 

iv는 객체마다 1개씩 있고,
cv는 따로 1개 있다. 

이점을 잘 이해하자.

[Ex6_3]

public class Ex6_3 {
    public static void main(String[] args){
        System.out.println("Card.width = " + Card.width);   // cv는 객체생성 하지 않고 사용 가능
        System.out.println("Card.height = " + Card.height); // cv는 객생성성 하지 않고 사용 가능

        Card c1 = new Card();
        c1.kind = "Heart";
        c1.number = 7;

        Card c2 = new Card();
        c2.kind = "Spade";
        c2.number = 4;

        System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 ("+Card.width+", "+Card.height+")");
        System.out.println("c2은 " + c2.kind + ", " + c2.number + "이며, 크기는 ("+Card.width+", "+Card.height+")");

        System.out.println("c1의 width와 height를 각각 50, 80으로 변경합니다.");

        c1.width = 50;          // 참조변수로 넓이를 변경하기 때문에 iv를 변경하는 것 같지만 실제로는 cv를 변경하는 것이다.
        c1.height = 80;         // 참조변수로 넓이를 변경하기 때문에 iv를 변경하는 것 같지만 실제로는 cv를 변경하는 것이다.
//        Card.width = 50;      // 이렇게 수정해주어야 좋은 코드이다.
//        Card.height = 80;     // 이렇게 수정해주어야 좋은 코드이다.

        System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 ("+Card.width+", "+Card.height+")");
        System.out.println("c2은 " + c2.kind + ", " + c2.number + "이며, 크기는 ("+Card.width+", "+Card.height+")");
    }
}

class Card {
    String kind;
    int number;
    static int width = 100;
    static int height = 250;
}

[실행 결과]

Card.width = 100
Card.height = 250
c1은 Heart, 7이며, 크기는 (100, 250)
c2은 Spade, 4이며, 크기는 (100, 250)
c1의 width와 height를 각각 50, 80으로 변경합니다.
c1은 Heart, 7이며, 크기는 (50, 80)
c2은 Spade, 4이며, 크기는 (50, 80)

이 예제에서 주의깊게 살펴봐야 할 부분은,

c1참조변수를 통해 cv값을 바꾸는 것인데, 
이게 참조변수를 사용해서 변수값을 바꾸기 때문에 iv값을 변경하는 것이라고 착각할 수 있지만,
실제로는 cv값을 변경하는 것이다.  왜냐하면, 넓이와 높이는 statitc이 붙어서, 카드클래스의 공통속성이기 때문이다.

따라서
c1.width = 50;
c1.height = 80;

이 코드를

Card.width = 50;
Card.height = 80; 으로 변경해주어, cv값을 바꾸는 것을 확실히 인지 할 수 있도록 작성하는 것이 좋다.

반응형

'JAVA' 카테고리의 다른 글

메서드 호출과 메서드의 실행흐름  (0) 2022.03.25
메서드란? 메서드의 선언부와 구현부  (0) 2022.03.25
선언위치 변수 종류  (0) 2022.03.25
클래스의 정의  (0) 2022.03.24
객체 배열  (0) 2022.03.24