JAVA

[ Java ] - 클래스 / 객체 / 인스턴스 (인스턴스의 생성과 사용법)

algml0703 2022. 12. 28. 07:37
반응형

  클래스 / 객체 / 인스턴스 (인스턴스의 생성과 사용법)

클래스란 객체를 정의해 놓은 설계도를 의미한다. 클래스는 기본적으로 객체를 생성하기 위해 사용된다. 반대로 객체를 클래스에 정의된 내용이 인스턴스화 되어 실제로 생성된 것을 의미한다. 예를 들어 집을 짓는다고 할 때 집을 짓기 위한 설계도는 클래스이고, 설계도에 따라 지어진 집은 객체이다. 프로그래밍에서 객체의 의미는 클래스에 정의된 내용대로 메모리에 생성된 것을 의미한다. 

클래스는 단순히 설계도에 불과하며, 해당 클래스를 실제로 사용하기 위해서는 반드시 인스턴스화하는 과정이 필요하다. 인스턴스화란 클래스를 객체 즉 실제로 사용할 수 있도록 생성하는 것을 의미한다.

* 객체와 인스턴스의 차이
객체와 인스턴스는 클래스에 정의된 내용에 따라 생성된 것이라는 점에서 같은 의미로 사용되지만, 엄격히 구분해본다면 객체는 모든 인스턴스를 포괄하는 의미를 가지고 있고, 인스턴스는 클래스를 통해 생성된 하나의 인스턴스라는 의미를 가진다는 점에서 구별된다.

클래스는 기본적으로 멤버변수와 메서드로 구성된다.

 *  인스턴스 생성과 사용법  

클래스명 변수명;
// 클래스의 객체를 참조하기 위한 참조변수 선언
변수명 = new 클래스명();
// 클래스의 객체를 생성 후, 해당 객체의 주소를 참조변수에 저장.

ex)

class Tv {
    String color;
    boolean power;
    int channel;

    void power( ){power = !power;}
    void channelUp() {++channel;}
    void channelDown() {--channel;}
}
public class TvTest {
    public static void main(String[] args) {
        Tv t;
        // Tv 클래스 타입으로 선언된 참조변수 t
        // 메모리에 Tv 클래스를 위한 공간이 확보된다.
        // 공간만 확보된 상태로, 아직 인스턴스가 생성된 것은 아니다.
        
        t = new Tv();
        // new에 의해 인스턴스가 생성되어 참조변수 t에 할당된 상태이다.
        t.channel = 7;
        t.channelDown();
        System.out.println("현재 채널은"+t.channel);
    }
}

* 참조변수의 공간을 확보하고, 반드시 new를 통해 인스턴스를 생성하고, 참조변수에 해당 인스턴스를 할당해주어야 참조변수를 통해 해당 인스턴스를 사용할 수 있다.

ex)

public class TvTest2 {
    public static void main(String[] args) {
        Tv t1 = new Tv();
        Tv t2 = new Tv();

        System.out.println("t1의 channel의 값은: "+t1.channel);
        System.out.println("t2의 channel의 값은: "+t2.channel);
        //        t1의 channel의 값은: 0
        //        t2의 channel의 값은: 0

        t2 = t1;

        t1.channelUp();

        System.out.println("t1의 channel의 값은: "+t1.channel);
        System.out.println("t2의 channel의 값은: "+t2.channel);
        //        t1의 channel의 값은: 1
        //        t2의 channel의 값은: 1

        t2.channel = 5;

        System.out.println("t1의 channel의 값은: "+t1.channel);
        System.out.println("t2의 channel의 값은: "+t2.channel);
        //        t1의 channel의 값은: 5
        //        t2의 channel의 값은: 5
    }
}

위의 코드에서 t1의 채널만을 변경하고, t2의 채널은 변경하지 않았음에도 불구하고, t2의 채널도 1이 된 것은, t2 = t1 을 통해 t2의 참조변수가 t1의 인스턴스가 생성된 주소를 가리키고 있기 때문이다. 즉 t2와 t1이 동일한 참조값(주소값)을 바라보고 있기 때문에 t1 또는 t2 변경시 해당 인스턴스 주소를 바라보고 있는 두 참조변수의 값 모두 변하게 되는 것이다. (이때 기존에 t2가 바라보고 있던 인스턴스의 주소값은 더이상 아무곳에서도 참조되고 있지 않기 때문에 heap 메모리에 할당된 t2 인스턴스의 메모리 공간은 가비지 컬렉터에 의해 자동적으로 메모리에서 제거된다.)

* 하나의 참조변수는 하나의 인스턴스 주소값만 가질 수 있다.
* 하나의 인스턴스는 여러 개의 참조변수에 의해 참조될 수 있다.

 *  배열에 인스턴스 할당하기  

Tv tvArr = new Tv[3];
Tv인스턴스 3개를 담을 수 있는 참조변수 tvArr. 
아직 메모리 공간만 확보한 것에 불과하며 인스턴스를 생성하여 할당한 것은 아니다.
배열의 각 요소는 null로 초기화되어 있는 상태이다.

ex)

public class TvTest2 {
//
    public static void main(String[] args) {
    //
        Tv[] tvArr = new Tv[3];
        System.out.println(tvArr[0]); // null
        System.out.println(tvArr[1]); // null
        System.out.println(tvArr[2]); // null

        Tv[] tvArr2 = {new Tv(), new Tv(),new Tv()};
        System.out.println(tvArr2[0]); // chapter06.Tv@7d417077
        System.out.println(tvArr2[1]); // chapter06.Tv@7dc36524
        System.out.println(tvArr2[2]); // chapter06.Tv@35bbe5e8
    }
}

위의 코드에서 처음 tvArr의 경우 null값으로 되어 있고, tvArr2의 경우 각 인스턴스가 생성되어 있는 메모리 주소값으로 되어 있는 것을 확인할 수 있다.

public class TvArr {
    public static void main(String[] args) {
        //
        Tv[] tvArr = new Tv[100];

        for (int i = 0; i < tvArr.length; i++) {
            tvArr[i] = new Tv();
        }

        for (int i = 0; i < tvArr.length; i++) {
            tvArr[i].channelUp();
            System.out.println(tvArr[i].channel);
            // 1
            // 1
            // 1
            ...
        }
    }
}

위와 같이 배열의 크기가 큰 경우에는 for문을 이용하여 인스턴스를 생성하여 참조변수에 할당할 수 도 있다.

 

출처 

자바의 정석 (남궁성)

반응형