자바 - 인스턴스 생성과 사용
tv의 일부기능을 구현한 클래스 예제를 통해 인스턴스가 어떻게 생성되고, 인스턴스의 속성과 메서드를 어떻게 사용하는지 단계별 과정과 특징을 알아보자.
Tv class : tv의 일부기능을 구현한 클래스
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | package doubles.study.soj.ch0602.oop.classobject; public class Tv { String color; //색상 boolean power; // 전원상태 int channel; // 채널 void power(){ // tv를 켜거나 끄는 기능을 하는 메서드 power = !power; } void channelDown(){ //tv의 채널을 낮추는 기능을 하는 메서드 -- channel; } void channelUp(){ //tv의 채널을 높이는 기능을 하는 메서드 ++ channel; } } | cs |
1. 인스턴스 생성과 인스턴스 속성, 메서드 사용
TvTest class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | package doubles.study.soj.ch0602.oop.classobject; public class TvTest { public static void main(String[] args){ Tv t; // 1. Tv인트턴스를 참조하기 위한 변수 t를 선언 // 2. tv클래스 타입의 참조변수 t를 선언, 메모리에 참조변수 t를 위한 공간이 마련 // 3. 인스턴스가 아직 생성되지 않았기 때문에 참조변수로는 아무것도 할 수 없음 t = new Tv(); // 4. Tv인스턴스 생성 // 5. 연산자 new에 의해 Tv클래스의 인스턴스가 메모리의 빈 공간에 생성 // 6. 주소가 0x100인 곳에 생성 // 7. 멤버변수는 각 자료형에 해당하는 기본값으로 초기화 // color(string) : null // power(boolaen) : false // channel(int) : 0 // 8. 대입연산자(=)에 의해서 생성된 객체의 주소값이 참조변수 t에 저장 // (참조변수 t를 통해 Tv인스턴스에 접근) // *이 때 참조변수 t는 'Tv인스턴스를 가리키고 있다.'또는 '참조하고 있다.'라고 한다. t.channel = 7; // 9. 참조변수 t에 저장된 주소에 있는 인스턴스의 멤버변수 channel에 7을 저장한다 // * 인스턴스의 멤버변수(속성)를 사용하려면 '참조변수.멤버변수'와 같이 사용하면된다. t.channelDown(); // 10. 참조변수 t가 참조하고 있는 Tv인스턴스의 channel메서드를 호출 // 11. channelDown메서드는 멤버변수 channel에 저장되어 있는 값을 1감소 System.out.println("현재 채널은"+t.channel+"입니다."); // 12. 참조변수 t가 참조하고 있는 Tv인스턴스의 멤버변수 channel에 저장되어있는 값 출력 } } | cs |
1, 2, 3 단계
4, 5, 6, 7, 8 단계
9 단계
10, 11 단계
12 단계
출력결과물
2. tv클래스의 인스턴스를 t1과 t2를 생성, 인스턴스 t1의 멤버변수인 channel의 값을 변경
TvTest2 class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | package doubles.study.soj.ch0602.oop.classobject; public class TvTest2 { public static void main(String[] args) { Tv t1 = new Tv(); // 1.Tv인스턴스를 사용하기 위해 객체 참조변수 t1선언, 인스턴스 생성 Tv t2 = new Tv(); // 2.Tv인스턴스를 사용하기 위해 객체 참조변수 t2선언, 인스턴스 생성 System.out.println("t1의 채널의 값은 "+t1.channel+" 입니다."); System.out.println("t2의 채널의 값은 "+t2.channel+" 입니다."); t1.channel = 7; // 3.channel의 값을 7로 세팅 System.out.println("t1의 채널의 값은 "+t1.channel+" (으)로 변경되었습니다."); System.out.println("t1의 채널의 값은 "+t1.channel+" 입니다."); System.out.println("t2의 채널의 값은 "+t2.channel+" 입니다."); } } | cs |
출력결과물
1 2 3 4 5 | t1의 채널의 값은 0 입니다. t2의 채널의 값은 0 입니다. t1의 채널의 값은 7 (으)로 변경되었습니다. t1의 채널의 값은 7 입니다. t2의 채널의 값은 0 입니다. | cs |
1, 2 단계
3 단계
3. tv클래스의 인스턴스를 t1과 t2를 생성, 인스턴스 t1이 저장하고 있는 값(주소)를 t2에 저장
TvTest3 class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 | package doubles.study.soj.ch0602.oop.classobject; public class TvTest3 { public static void main(String[] args) { Tv t1 = new Tv(); // 1. Tv인스턴스를 사용하기 위해 객체 참조변수 t1선언, 인스턴스 생성 Tv t2 = new Tv(); // 2. Tv인스턴스를 사용하기 위해 객체 참조변수 t2선언, 인스턴스 생성 System.out.println("t1의 채널의 값은 "+t1.channel+" 입니다."); System.out.println("t2의 채널의 값은 "+t2.channel+" 입니다."); t2 = t1; // 3. t1이 저장하고 있는 값(주소)을 t2에 저장 /* t1은 참조변수이므로 인스턴스의 주소를 저장하고 있다. * 이 문장이 실행되면 t2가 가지고 있던 값은 잃어버리게 되고, * t1이 가지고 있던 값이 t2에 저장된다. * 그렇게 되면 t2도 t1이 참조하고 있던 인스턴스를 참조하게 되고, * t2가 원래 참조하고 있던 인스턴스는 더이상 사용할 수 없게 된다. */ t1.channel = 7; // 4. channel의 값을 7로 저장 System.out.println("t1의 채널의 값은 "+t1.channel+" (으)로 변경되었습니다."); System.out.println("t1의 채널의 값은 "+t1.channel+" 입니다."); System.out.println("t2의 채널의 값은 "+t2.channel+" 입니다."); } } | cs |
1, 2 단계
3 단계
4 단계
출력결과물
4. 객체 배열
많은 수의 객체를 다뤄야할 때, 배열로 다루면 편리할 것이다. 객체 역시 배열로 다루는 것이 가능하며, 이를 '객체 배열'이라고 한다. 객체 배열 안에 객체가 저장되는 것이 아니고, 객체의 주소가 저장된다.
즉, 객체 배열은 참조변수들을 하나로 묶은 참조변수 배열인 것이다.
TvTest4 class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 | package doubles.study.soj.ch0602.oop.classobject; public class TvTest4 { public static void main(String[] args) { // Tv tv1, tv2, tv3; --> Tv[] tvArr = new Tv[3]; Tv[] tvArr = new Tv[3]; // 길이가 3인 Tv타입의 참조변수배열을 선언 // 객체 배열을 생성하는 것은 , 객체를 다루기 위한 참조변수들이 만들어진 것일 뿐, // 객체가 생성되지 않았다. 객체를 생성해서 객체배열의 각 요소에 저장하는 것을 // 잊어서는 안된다. // 객체를 생성해서 배열의 각 요소에 저장 /*tvArr[0] = new Tv(); tvArr[1] = new Tv(); tvArr[2] = new Tv();*/ // Tv[] tvArr = { new Tv(), new Tv(), new Tv() }; // 배열의 초기화 블럭을 사용하면, 한줄로 요약하여 작성할 수 있다. // 만약 다뤄야할 객체의 수가 많다면 for문을 사용한다. // Tv객체를 생성해서 Tv객체 배열의 각요소에 저장 for(int i=0; i<tvArr.length; i++){ tvArr[i] = new Tv(); tvArr[i].channel = i+10; // tvArr[i]의 channel에 i+10을 저장 } for(int i=0; i<tvArr.length; i++){ tvArr[i].channelUp(); // tvArr[i]의 메서드 호출, 채널 1 증가 System.out.printf("tvArr[%d].channel=%d%n", i, tvArr[i].channel); } } } | cs |
출력결과물
5. 클래스의 또다른 정의
1) 데이터와 함수의 결함
변수 - 하나의 데이터를 저장할 수 있는 공간
배열 - 같은 종류의 여러 데이터를 하나의 집합으로 저장할 수 있는 공간
구조체 - 서로 관련된 여러 데이터를 종류에 관계없이 하나의 집합으로 저장할 수 있는 공간
클래스 - 데이터와 함수의 결합(구조체 + 함수)
2) 사용자 정의 타입
프로그래밍언어에서 제공하는 자료형(primitive type) 외에 프로그래머가 서로 관련된 변수들을 묶어서 하나의 타입으로 새로 추가하는 것을 사용자정의 타입(user-defined type)이라고 한다.
※ 핵심 내용 및 주의 사항
1. 인스턴스는 참조변수를 통해서만 다룰 수 있으며, 참조변수의 타입은 인스턴스의 타입과 일치해야 한다.
2. 같은 클래스로부터 생성되었을지라도 각 인스턴스의 속성(멤버변수)은 서로 다른 값을 유지할 수 있으며, 메서드의 내용은 모든 인스턴스에 대해 동일하다.
3. 참조변수에는 하나의 값(주소)만이 저장될 수 있으므로 둘 이상의 참조변수가 하나의 인스턴스를 가리키(참조하는) 것은 가능하지만 하나의 참조변수로 여러 개의 인스턴스를 가리키는 것은 불가능하다.
4. 모든 배열이 그렇듯이 객체 배열도 같은 타입의 객체만 저장이 가능하다.
출처 및 참고 : 자바의 정석 234 ~ 245p