관리 메뉴

나구리의 개발공부기록

자바의 정석 기초편 ch6 - 5 ~ 8[한파일에 여러 클래스 작성하기,객체의 생성과 사용, 객체의 배열] 본문

유튜브 공부/JAVA의 정석 기초편(유튜브)

자바의 정석 기초편 ch6 - 5 ~ 8[한파일에 여러 클래스 작성하기,객체의 생성과 사용, 객체의 배열]

소소한나구리 2023. 11. 14. 16:45

1) 한파일에 여러 클래스 작성

  • 한 파일에 여러 클래스를 작성해도 되긴하지만 가능하면 하나의 소스파일에는 하나의 클래스만 생성하는 것이 바람직함.

(1) public class

  • 다른 패키지에서도 사용 가능한 클래스
  • class앞에 아무것도 없으면 default class (package-private)
  • 제어자에 대한 상세한 내용은 7장에서 배움
  • public class가 있는 경우에는 소스파일의 이름과 public class의 이름과 일치 해야하며 둘 이상의 public class는 존재하면 안됨
    • Hello2.java
    • public class Hello2 {}
    • class Hello3 {}
  • public class가 없는 경우에는 소스파일의 이름을 여러 클래스 중 1개와 일치해야함
    • Hello2.java
    • class Hello2 {}
    • class Hello3 {}

(2) 주요 에러 상황

  • 하나의 소스 파일에 둘 이상의 public class가 존재하는 경우
  • 소스파일의 이름과 public class의 이름이 일치 하지 않는 경우(대소문자 포함)
  • 소스파일의 이름과 main 메소드가 들어있는 class와 이름이 일치하지 않는 경우 -> 에러는 나지 않지만 Java는 소스파일 이름이 아닌 class 이름을 기준으로 main 메소드를 찾아 실행하기 때문에 예상과 다른 결과가 나올 수 있음

(3) 이클립스에서 메인 class 지정하기

  • Run configurations -> Main class 수정

2) 객체의 생성 과정

(1) 클래스 작성(설계도 작성)

  • 아래의 이미지처럼 클래스(설계도)를 작성해두었다고 가정
  • Tv 클래스에 각 변수와 메서드들이 정의 되어있음

미리 생성해 놓은 Tv클래스(설계도)

(2) 객체의 생성

  • 클래스명 변수명;  -> 클래스의 객체를 참조하기 위한 참조변수를 선언
  • 변수명 = new 클래스명(); -> 클래스의 객체를 생성 후, 객체의 주소를 참조 변수에 저장
  • Tv t;  -> Tv클래스 타입의 참조변수 t(리모콘)를 선언
  • t = new Tv();
    • new 연산자로 Tv 인스턴스를 생성한 후 생성된 인스턴스의 주소(참조값)를 참조변수 t에 저장
    • 리모콘(참조변수)과  TV(객체)를 연결했다고 이해하면 됨
    • Tv t = new Tv();  처럼 위의 2문장을 한번에 작성할 수도 있음

** 참조변수(리모콘) - 객체를 다루려면 참조변수가 필요하며 java에서는 참조변수 없이 객체를 다룰 수 있는 방법이 없음

 

(3) 객체의 사용

  • 참조변수.변수 = 값; -> 변수사용
    • t.channel = 7;  -> 참조변수 t가 가리키는 Tv 인스턴스의 멤버변수 channel의 값을 7로 변경(변수사용)
  • 참조변수.메서드(매개변수); -> 메서드 호출
    • t.channeldown(); -> 참조변수 t가 가리키는 Tv 인스턴스에 정의된 메서드 channelDown()을 호출(메서드호출)하면 메서드의 정의한 기능이 동작하여 채널을 1 감소시킴

(4) 객체가 2개 생성 된 예제

Tv t1 = new Tv();
Tv t2 = new Tv();

t1.channel = 7; // Tv인스턴스의 참조변수t1이 가리키는 멤버변수channel에 7을 저장

System.out.println("현재 채널은 "+ t1.channel + "입니다.") // 출력결과 -> 현재 채널은 7 입니다.
System.out.println("현재 채널은 "+ t2.channel + "입니다.") // 출력결과 -> 현재 채널은 0 입니다.
  • 각 객체마다 별도의 저장공간이(참조변수) 생길 수 있음

참조변수 t1과 t2가 가리키는 객체가 서로 다름

 
(5) 추가 예제

  • 서로다른 참조변수를 같은 객체를 사용하도록 변경
  • 사용할 수 없는 객체는 가비지컬렉터가 자동으로 메모리를 제거함
  • t2 = t1; 코드로 인하여 t2에 생성된 Tv인스턴스의 참조가 끊겨버리고 t1이 가리키는 참조주소가 저장되어 t1과 t2가 동일한 참조를 가리키게되어 t1이 변경되어도 t2도 변경이 됨
  • t2가 가리키던 객체는 가비지 컬렌션의 대상이 됨
Tv t1 = new Tv();
Tv t2 = new Tv();

// t2의 참조변수 주소가 t1으로 변경되어 t2의 객체와 연결이 끊기고 t1의 객체에 연결이 됨.
t2 = t1; // 변수 t1의 값을 t2에 저장

t1.channel = 7; // Tv인스턴스의 참조변수t1이 가리키는 멤버변수channel에 7을 저장

System.out.println("현재 채널은 "+ t1.channel + "입니다.") // 출력결과 -> 현재 채널은 7입니다.
System.out.println("현재 채널은 "+ t2.channel + "입니다.") // 출력결과 -> 현재 채널은 7입니다.

참조변수 t1과 t2가 가리키는 객체가 같음

  1. 하나의 인스턴스를 여러 개의 참조변수가 가리키는 경우는 가능
  2. 여러 인스턴스를 하나의 참조변수가 가리키는 경우는 불가능 (변수는 하나의 값만 저장 가능)

 
(7) 실습

  • 위에서 설명한 내용을 실습
public class ex6_1 { 
	public static void main(String args[]) { 
		Tv t;                 // Tv인스턴스를 참조하기 위한 변수 t를 선언       
		t = new Tv();         // Tv인스턴스를 생성한다. 
		t.channel = 7;        // Tv인스턴스의 멤버변수 channel의 값을 7로 한다. 
		t.channelDown();      // Tv인스턴스의 메서드 channelDown()을 호출한다. 
		System.out.println("현재 채널은 " + t.channel + " 입니다."); 
	} 
}

class Tv { 
	// Tv의 속성(멤버변수)
	String color;           // 색상 
	boolean power;         	// 전원상태(on/off) 
	int channel;           	// 채널 

	// Tv의 기능(메서드) 
	void power()   { power = !power; }  // TV를 켜거나 끄는 기능을 하는 메서드  
	void channelUp()   {  ++channel; }  // TV의 채널을 높이는 기능을 하는 메서드 
	void channelDown() { --channel; }   // TV의 채널을 낮추는 기능을 하는 메서드  
}

출력결과
현재 채널은 6 입니다.
public class ex6_2 {
	public static void main(String args[]) {
		Tv t1 = new Tv();  // Tv t1; t1 = new Tv();를 한 문장으로 가능
		Tv t2 = new Tv();
		System.out.println("t1의 channel값은 " + t1.channel + "입니다.");
		System.out.println("t2의 channel값은 " + t2.channel + "입니다.");
		
		t1.channel = 7;    // channel 값을 7으로 한다.
		t2 = t1; // t1의 참조변수 값을 t2에 입력

		System.out.println("t1의 channel값을 7로 변경하였습니다.");

		System.out.println("t1의 channel값은 " + t1.channel + "입니다.");
		System.out.println("t2의 channel값은 " + t2.channel + "입니다.");
	}
}

출력결과

t1의 channel값은 0입니다.
t2의 channel값은 0입니다.
t1의 channel값을 7로 변경하였습니다.
t1의 channel값은 7입니다.
t2의 channel값은 7입니다.

 


3) 객체 배열

  • 참조변수들의 배열
Tv tv1, tv2, tv3;        // Tv 타입 참조변수 3개
Tv[] tvArr = new Tv[3];  // 길이가 3인 Tv타입의 참조변수 배열

 

(1) 객체배열 초기화

  • 객체를 생성해서 배열의 각 요소에 저장
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() } // 위 3문장을 한번에 저장

 

(2) 각각의 참조변수가 각각의 객체를 참조

  • 각 참조변수 t1, t2, t3에 new Tv()를 저장
  • 각 참조변수가 묶이지 않고 독립적으로 객체를 가리킴
Tv t1 = new Tv();
Tv t2 = new Tv();
Tv t3 = new Tv();

 

(3) 객체 배열

  • tvArr이라는 객체 배열의 각 인덱스가 생성된 객체를 참조함
  • 각 객체의 참조값을 하나의 배열에서 관리하고, 그 배열의 요소인 인덱스번호마다 참조값이 초기화 되어있다고 이해하면 됨
  • Tv[] tvArr = new Tv[3];처럼 객체 배열을 생성할 경우 각 요소는 null이 되기 때문에 별도로 생성된 객체 배열의 각 인덱스에 객체를 별도로 초기화해주는 코드가 필요함
Tv[] tvArr = new Tv[3];  // 길이가 3인 Tv타입의 객체 배열, 각배열의 인덱스의 값은 null
tvArr[0] = new Tv();     // 객체 배열 tvArr의 각 인덱스에 Tv객체를 생성하여 참조값을 저장
tvArr[1] = new Tv();
tvArr[2] = new Tv();

// 객체 배열을 선언함과 동시에 각 배열의 요소에 Tv인스턴스를 생성하고 참조값을 저장
Tv[] tvArr = { new Tv(), new Tv(), new Tv() }
좌) 1번 이미지 , 우) 2번 이미지

(3) 주의점

  • 참조변수 배열만 생성해놓고 객체를 생성하지 않거나, 객체를 참조변수에 초기화 하지 않는 경우가 많음

 

** 출처 : 남궁성의 정석코딩_자바의정석