자바의 정석 <기초편> 📌chapter6. 객체지향 프로그래밍 Ⅰ

모깅·2023년 1월 31일
0

📖 01. 객체지향 언어

  • 객체지향언어는 기존의 프로그래밍 언어에 몇 가지 새로운 규칙을 추가한 언어이다.
  • 객체지향언어의 주요 특징
    1. 코드의 재사용성이 높다.
    -> 새로운 코드를 작성할 때 기존의 코드를 이용하여 쉽게 작성할 수 있다.
    2. 코드의 관리가 용이하다.
    -> 코드간의 관계를 이용해서 적은 노력으로 쉽게 코드를 변경 할 수 있다.
    3. 신뢰성이 높은 프로그래밍을 가능하게 한다.
    -> 제어자와 메서드를 이용해서 데이터를 보호하고 올바른 값을 유지하도록 하며, 코드의 중복을 제거하여 코드의 불일치로 인한 오동작을 방지 할 수 있다.
    • 가장 큰 장점
      -> '코드의 재사용성이 높고 유지보수가 용이하다.'
  • 객체지향개념을 학습 할 때!
    ->재사용성과 유지보수 그리고 중복된 코드의 제거, 이 세가지 관점에서 보면 보다 쉽게 이해 가능 할 것임!

📖 02. 클래스와 객체

  • 클래스의 정의 : 클래스란 객체를 정의해 놓은 것
    클래스의 용도 : 클래스는 객체를 생성하는데 이용
    -> 프로그래밍에서 객체는 클래스에 정의돈 내용대로 메모리에 생성된 것

  • 객체의 정의 : 실제로 존재하는 것. 사물 또는 개념
    객체의 용도 : 객체가 가지고 있는 기능과 속성에 따라 다름

    유형의 객체 : 책상, 의자, 자동차, TV와 같은 사물
    무형의 객체 : 수학공식, 프로그램 에러와 같은 논리나 개념

-> 객체를 사용한다는 것은 객체가 가지고 있는 속성기능을 사용한다는 뜻이다.


📖 03. 객체의 구성요소 - 속성과 기능

  • 객체는 속성과 기능의 집합이라고 할 수 있다.
    -> 객체가 가지고 있는 속성과 기능을 그 객체의 멤버(구성원, member)라 한다.
    -> 속성(property) => 멤버변수(variable)
    -> 기능(function) => 메서드(method)

📖 04. 객체와 인스턴스

  • 클래스로부터 객체를 만드는 과정을 클래스의 인스턴스화(instantiate)라고 하며, 어떤 클래스로부터 만들어진 객체를 그 클래스의 인스터스(instance)라고 한다.
  • '책상은 객체다.' , '책상은 책상 클래스의 인스턴스다.'
    -> 똑같다고 생각하되 문맥에 맞게 적용 시키면 된다.

📖 05. 한 파일에 여러 클래스 작성하기


-> 소스파일의 이름과 main이 존재하는 클래스를 일치시켜야 이클립스가 바로 main있는 클래스를 시작 할 수 있다.


📖 06. 객체의 생성과 사용

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

<예제 6-1 >

✍️ 입력

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 입니다.

-> 참조변수는 생성된 객체의 주소를 참조하고 있다.


📖 07. 객체의 생성과 사용 예제

<예제 6-2 >

✍️ 입력

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으로 한다.
		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값은 0입니다.


📖 08. 객체배열

  • 참조변수의 배열이다.

-> 객체배열 생성하고 꼭 각 인덱스마다 객체 생성해주기!


📖 09. 클래스의 정의(1) - 데이터와 함수의 결합

  • 클래스는 크게 3가지로 생각 할 수 있다.
  1. 설계도
  2. 데이터와 함수의 결합
  3. 사용자 정의 타입
    -> 2번에 대해서 알아보자.

📖 10. 클래스의 정의(2) - 사용자 정의 타입

  • 사용자 정의 타입 : 프로그래머가 서로 관련된 변수들을 묶어서 하나의 타입으로 새로 추가한 것.

    -> 클래스를 선언하면 다음과 같이 간단히 나타낼 수 있다.

    -> 메모리가 잡히는 모습

    -> 객체배열 사용하여 관련있는 것들끼리 묶을 수 있다.

📖 11. 선언위치에 따른 변수의 종류


📖 12. 클래스 변수와 인스턴스 변수


-> 폭, 넓이는 카드 모두 공통이므로 클래스 변수(static variable)로 선언하자.
-> 무늬, 숫자는 각 인스턴스마다 고유해야 하므로 인스턴스 변수(instance variable)로 선언하자.


📖 13. 클래스 변수와 인스턴스 변수 예제

<예제 6-3 >

✍️ 입력

class Ex6_3 {
	public static void main(String args[]) {
		System.out.println("Card.width = " + Card.width);
		System.out.println("Card.height = " + Card.height);

		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 + "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
		System.out.println("c2는 " + c2.kind + ", " + c2.number + "이며, 크기는 (" + c2.width + ", " + c2.height + ")");
		System.out.println("c1의 width와 height를 각각 50, 80으로 변경합니다.");
		c1.width = 50;
		c1.height = 80;

		System.out.println("c1은 " + c1.kind + ", " + c1.number + "이며, 크기는 (" + c1.width + ", " + c1.height + ")");
		System.out.println("c2는 " + c2.kind + ", " + c2.number + "이며, 크기는 (" + c2.width + ", " + c2.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)

-> 클래스 변수는 클래스이름.클래스변수 형태로 사용하자.
why? 인스턴스 변수롤 착각 할 수 있다.
-> 물론, 객체이름.인스턴스변수로 사용해도 클래스 변수의 값은 바뀐다.
why? 클래스 변수는 모든 인스턴스가 공유하고 있기 때문이다.


📖 14. 메서드란? && 15. 메서드의 선언부 && 16. 메서드의 구현부



-> 반환값은 최대 한 개이다. 여러개를 반환하고 싶다면 배열이나 클래스를 로 반환하자.
-> 매개변수도 지역변수이다.


📖 17. 메서드의 호출 && 18. 메서드의 실행 흐름 && 19. 메서드의 실행 흐름 예제

<예제 6-4 >

✍️ 입력

class Ex6_4 {
	public static void main(String args[]) {
		MyMath mm = new MyMath();
		long result1 = mm.add(5L, 3L);
		long result2 = mm.subtract(5L, 3L);
		long result3 = mm.multiply(5L, 3L);
		double result4 = mm.divide(5L, 3L);

		System.out.println("add(5L, 3L) = " + result1);
		System.out.println("subtract(5L, 3L) = " + result2);
		System.out.println("multiply(5L, 3L) = " + result3);
		System.out.println("divide(5L, 3L) = " + result4);
	}
 }

 class MyMath {
	long add(long a, long b) {
		long result = a + b;
		return result;
	//	return a + b;	// 위의 두 줄을 이와 같이 한 줄로 간단히 할 수 있다.
	}
	long subtract(long a, long b) { return a - b; }
	long multiply(long a, long b) { return a * b; }
	double divide(double a, double b) {
		return a / b;
	}
 }

💻 출력
add(5L, 3L) = 8
subtract(5L, 3L) = 2
multiply(5L, 3L) = 15
divide(5L, 3L) = 1.6666666666666667


📖 20. return문 && 21. 반환값

  • 주의사항

📖 22. 호출스택(call stack)

  • 호출스택은 메서드의 작업에 필요한 메모리 공간을 제공한다.


    -> 코드를 보고 호출스택이 쌓이는 것을 그릴 줄 알아야 함!

<예제 6-5 >

✍️ 입력

class Ex6_5 {
	public static void main(String[] args) {
		System.out.println("Hello");		
	}
}

💻 출력
Hello


📖 23. 기본형 매개변수

기본형 매개변수 : 변수의 값을 읽기만 할 수 있다.(read only)
참조형 매개변수 : 변수의 값을 읽고 변경할 수 있다.(read & write)

<예제 6-6 >

✍️ 입력

class Data { int x; }

class Ex6_6 {
	public static void main(String[] args) {
		Data d = new Data();
		d.x = 10;
		System.out.println("main() : x = " + d.x);

		change(d.x);
		System.out.println("After change(d.x)");
		System.out.println("main() : x = " + d.x);
	}

	static void change(int x) {  // 기본형 매개변수
		x = 1000;
		System.out.println("change() : x = " + x);
	}
}

💻 출력
main() : x = 10
change() : x = 1000
After change(d.x)
main() : x = 10

-> 호출스택 그림으로 그릴 줄 알아야 함!
-> 'd.x'의 값이 변경된 것이 아니라, change메서드의 매개변수 x의 값이 변경된 것이다. 즉, 원본은 건들 수 없다. (기본형 - only read)


📖 24. 참조형 매개변수

<예제 6-7 >

✍️ 입력

class Data2 { int x; }

class Ex6_7 {
	public static void main(String[] args) {
		Data2 d = new Data2();
		d.x = 10;
		System.out.println("main() : x = " + d.x);

		change(d);
		System.out.println("After change(d)");
		System.out.println("main() : x = " + d.x);
	}

	static void change(Data2 d) { // 참조형 매개변수
		d.x = 1000;
		System.out.println("change() : x = " + d.x);
	}
}

💻 출력
main() : x = 10
change() : x = 1000
After change(d)
main() : x = 1000

-> 매개변수가 참조형이므로 주소를 넘긴다.
-> 그림으로 그릴 수 있어야 한다!


📖 25. 참조형 반환타입

<예제 6-8 >

✍️ 입력

class Data3 { int x; }

class Ex6_8 {
	public static void main(String[] args) {
		Data3 d = new Data3();
		d.x = 10;

		Data3 d2 = copy(d); 
		System.out.println("d.x ="+d.x);
		System.out.println("d2.x="+d2.x);
	}

	static Data3 copy(Data3 d) {
		Data3 tmp = new Data3();    // 새로운 객체 tmp를 생성한다.

		tmp.x = d.x;  // d.x의 값을 tmp.x에 복사한다.

		return tmp;   // 복사한 객체의 주소를 반환한다.
	}
}

💻 출력
d.x =10
d2.x=10

-> 똑같다. 단지 주소를 반환할 뿐이다. 그림으로 그려서 이해해보자.


📖 26. static 메서드와 인스턴스 메서드

-> 클래스 메서드에서 인스턴스변수를 사용 할 수 없는 이유?
클래스 메서드는 객체 생성 없이 사용 할 수 있다. 이 때 객체는 인스턴스 변수의 묶음으로 간단히 설명 할 수 있다.
따라서 클래스 메서드 입장에서는 인스턴스 변수의 묶음이 존재하는지, 존재하지 않는지 알 수 없다.


📖 27. static 메서드와 인스턴스 메서드 예제

<예제 6-9 >

✍️ 입력

class MyMath2 {
	long a, b;

	// 인스턴스 변수 a, b만을 잉요해서 작업하므로 매개변수가 필요없다.
	long add()		{ return a + b; }  // a, b는 인스턴스 변수
	long subtract() { return a - b; }
	long multiply() { return a * b; }
	double divide() { return a / b; }

	// 인스턴스 변수와 관계없이 매개변수만으로 작업이 가능하다.
	static long   add(long a, long b)		 { return a + b; }  // a, b는 지역변수
	static long   subtract(long a, long b)   { return a - b; }
	static long   multiply(long a, long b)   { return a * b; }
	static double divide(long a, long b) { return a / (double)b; }
	
}


class Ex6_9 {
	public static void main(String args[]) {
		// 클래스 메서드 호출. 인스턴스 생성없이 호출가능
		System.out.println(MyMath2.add(200L, 100L));
		System.out.println(MyMath2.subtract(200L, 100L));
		System.out.println(MyMath2.multiply(200L, 100L));
		System.out.println(MyMath2.divide(200L, 100L));

		MyMath2 mm = new MyMath2(); // 인스턴스를 생성
		mm.a = 200L;
		mm.b = 100L;
		// 인스턴스 메서드는 객체생성 후에만 호출이 가능함.
		System.out.println(mm.add());
		System.out.println(mm.subtract());
		System.out.println(mm.multiply());
		System.out.println(mm.divide());
   }
}

💻 출력
300
100
20000
2.0
300
100
20000
2.0


📖 28. static을 언제 붙여야 할까?

1. 클래스를 설계할 때, 멤버변수 중 모든 인스턴스에 공통으로 사용한는 것에 static을 붙인다.
-> 생성된 각 인스턴스는 서로 독립적이기 때문에 각 인스턴스의 변수(iv)는 서로 다른 값을 유지한다. 그러나 모든 인스턴스에서의 같은 값이 유지되어야 하는 변수는 static을 붙여서 클래스변수로 정의해야 한다.

2. 클래스 변수(static)는 인스턴스를 생성하지 않아도 사용 할 수 있다.
-> static이 붙은 변수(클래스 변수)는 클래스가 메모리에 올라갈 때 이미 자동적으로 생성되기 때문이다.

3. 클래스 메서드(static메서드)는 인스턴스 변수를 사용 할 수 없다.
-> 클래스메서드(static이 붙은 메서드)는 인스턴스 생성 없이 호출가능하므로 클래서 메서드가 호출되었을 때 인스턴스가 존재하지 않을 수 있다.
따라서, 클래스 메서드에서 인스턴스변수의 사용을 금지한다.
-> 반면에 인스턴스변수나 인스턴스메서드에서는 static이 붙은 멤버들을 사용한는 것이 언제나 가능하다. 인스턴스 변수가 존재한다는 것은 static변수가 이미 메모리에 존재한다는 것을 의미하기 때문이다.

4. 메서드 내에서 인스턴스 변수를 사용하지 않는다면, static을 붙이는 것을 고려한다.
-> 인스턴스를 필요로 하지 않는다면 static을 붙이자. 메서드 호출시간이 짧아지므로 성능이 향상된다. static을 안 붙인 메서드(인스턴스메서드)는 실행 시 호출되어야할 메서드를 찾는 과정이 추가적으로 필요하기 때문에 시간이 더 걸린다.

  • 정리
    1. 클래스의 멤버변수 중 모든 인스턴스에 공통된 값을 유지해야하는 것이 있는지 살펴보고 있으면 static을 붙여준다
    2. 작성한 메서드 중에서 인스턴스 변수나 인스턴스 메서드를 사용하지 않는 메서드에 static을 붙일 것을 고려한다.

📖 29. 메서드 간의 호출과 참조


-> static메서드에서 인스터스 변수나 인스턴스 메서드를 사용 및 호출 할 수 없다.
-> why?
인스턴스 멤버가 존재하는 시점에 클래스 멤버는 항상 존재하지만, 클래스멤버가 존재하는 시점에 인스턴스 멤버가 존재하지 않을 수도 있기 때문이다.


📖 30. 오버로딩(overloading)

  • 오버로딩 : 한 클래스 내에 같은 이름의 메서드를 여러 개 정의 하는 것
  • 오버로딩 조건
    1. 메서드 이름이 같아야 한다.
    2. 매개변수의 개수 또는 타입이 달라야 한다.
    3. 반한 타입은 관계없다.


📖 31. 오버로딩(overloading) 예제

<예제 6-10 >

✍️ 입력

class Ex6_10 {
	public static void main(String args[]) {
		MyMath3 mm = new MyMath3();
		System.out.println("mm.add(3, 3) 결과:"    + mm.add(3,3));
		System.out.println("mm.add(3L, 3) 결과: "  + mm.add(3L,3));
		System.out.println("mm.add(3, 3L) 결과: "  + mm.add(3,3L));
		System.out.println("mm.add(3L, 3L) 결과: " + mm.add(3L,3L));

		int[] a = {100, 200, 300};
		System.out.println("mm.add(a) 결과: " + mm.add(a));
   }
}

class MyMath3 {
	int add(int a, int b) {
		System.out.print("int add(int a, int b) - ");
		return a+b;
	}
	
	long add(int a, long b) {
		System.out.print("long add(int a, long b) - ");
		return a+b;
	}
	
	long add(long a, int b) {
		System.out.print("long add(long a, int b) - ");
		return a+b;
	}

	long add(long a, long b) {
		System.out.print("long add(long a, long b) - ");
		return a+b;
	}

	int add(int[] a) {		// 배열의 모든 요소의 합을 결과로 돌려준다.
		System.out.print("int add(int[] a) - ");
		int result = 0;
		for(int i=0; i < a.length;i++) 
			result += a[i];
		
		return result;
	}
}

💻 출력
int add(int a, int b) - mm.add(3, 3) 결과:6
long add(long a, int b) - mm.add(3L, 3) 결과: 6
long add(int a, long b) - mm.add(3, 3L) 결과: 6
long add(long a, long b) - mm.add(3L, 3L) 결과: 6
int add(int[] a) - mm.add(a) 결과: 600


📖 32. 생성자


📖 33. 기본 생성자(default constructor)


📖 34. 매개변수가 있는 생성자


📖 35. 매개변수가 있는 생성자 예제

인스턴스를 생성할 때는 다음의 2가지 사항을 결정해야 한다.
1. 클래스 - 어떤 클래스의 인스턴스를 생성할 것인가?
2. 생성자 - 선택한 클래스의 어떤 생성자로 인스턴스를 생성할 것인가?

<예제 6-12 >

✍️ 입력

class Car {
	String color;		// 색상
	String gearType;	// 변속기 종류 - auto(자동), manual(수동)
	int door;			// 문의 개수

	Car() {}

	Car(String c, String g, int d) {
		color = c;
		gearType = g;
		door = d;
	}
}

class Ex6_12 {
	public static void main(String[] args) {
		Car c1 = new Car();
		c1.color    = "white";
		c1.gearType = "auto";
		c1.door = 4;

		Car c2 = new Car("white", "auto", 4);

		System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType+ ", door="+c1.door);
		System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType+ ", door="+c2.door);
	}
}

💻 출력
c1의 color=white, gearType=auto, door=4
c2의 color=white, gearType=auto, door=4


📖 36. 생성자에서 다른 생성자 호출하기 - this()

<예제 6-13 >

✍️ 입력

class Car2 {
	String color;		// 색상
	String gearType;	// 변속기 종류 - auto(자동), manual(수동)
	int door;			// 문의 개수

	Car2() {
		this("white", "auto", 4);
	}

	Car2(String color) {
		this(color, "auto", 4);
	}

	Car2(String color, String gearType, int door) {
		this.color = color;
		this.gearType = gearType;
		this.door = door;
	}
}
class Ex6_13 {
	public static void main(String[] args) {
		Car2 c1 = new Car2();	
		Car2 c2 = new Car2("blue");

		System.out.println("c1의 color=" + c1.color + ", gearType=" + c1.gearType+ ", door="+c1.door);
		System.out.println("c2의 color=" + c2.color + ", gearType=" + c2.gearType+ ", door="+c2.door);
	}
}

💻 출력
c1의 color=white, gearType=auto, door=4
c2의 color=blue, gearType=auto, door=4


📖 37. 객체 자신을 가리키는 참조변수 - this

  • 'this'를 사용할 수 있는 것은 인스턴스멤버뿐이다. static메서드(클래스 메서드)에서는 인스턴스 멤버들을 사용할 수 없는 것처럼, 'this' 역시 사용 할 수 없다
    -> why?
    static메서드는 인스턴스를 생성하지 않고도 호출될 수 있으므로 static메서드가 호출된 시점에 인스턴스가 존재하지 않을 수도 있기 때문이다.

📖 38. 변수의 초기화

-> 스택에서 지역변수는 빠르게 생기고 사라진다. 따라서 초기화를 매 번 해주게 되면 성능이 저하된다.
-> 초기화 해주지 않는다면 다른 메소드의 모르는 값으로 초기화 된다.
따라서, 어떤 값인지 알 수 없기 때문에 컴파일과정에서 =를 통해 변수에 넣을 수 없게 된다.


📖 39. 멤버변수의 초기화

1. 클래스 변수(cv) 초기화 -> 인스턴스 변수(iv) 초기화
2. 자동 초기화 -> 명시적 초기화(간단) -> 초기화 블럭, 생성자(복잡)

-> 자동 초기화 : '0'으로 초기화
-> 간단 초기화 : '='으로 초기화
-> 복잡 초기화 블럭
1. {} (iv 초기화)
2. 생성자 (iv 초기화)
3. static {} (cv 초기화)


📖 40. 멤버변수의 초기화 예제1

<예제 6-14 >

✍️ 입력

class Ex6_14 {
	static {
		System.out.println("static { }");
	}

	{
		System.out.println("{ }");
	}

	public Ex6_14() {
		System.out.println("생성자");
	}

	public static void main(String args[]) {
		System.out.println("Ex6_14 bt = new Ex6_14(); ");
		Ex6_14 bt = new Ex6_14();

		System.out.println("Ex6_14 bt2 = new Ex6_14(); ");
		Ex6_14 bt2 = new Ex6_14();
	}
}

💻 출력
static { }
Ex6_14 bt = new Ex6_14();
{ }
생성자
Ex6_14 bt2 = new Ex6_14();
{ }
생성자

-> 예제가 실행되면서 Ex6_14이 메모리에 로딩될 때, 클래스 초기화 블럭이 가장 먼저 수행되어 'static {}'이 화면에 출력된다. 그 다음에 main메서드가 수행되어 Ex6_14의 인스턴스가 생성되면서 인스턴스 초기화 블럭이 먼저 수행되고, 끝으로 생성자가 수행된다.
-> 클래스 초기화 블럭은 처음 메모리에 로딩될 때 한번만 수행되었지만, 인스턴스 초기화 블럭은 인스턴스가 생성될 때 마다 수행된다.

업로드중..


📖 41. 멤버변수의 초기화 예제2

<예제 6-15 >

✍️ 입력

class Ex6_15 {
	static int[] arr = new int[10];

	static {
		for(int i=0;i<arr.length;i++) {
			// 1과 10사이의 임의의 값을 배열 arr에 저장한다.
			arr[i] = (int)(Math.random()*10) + 1;
		}
	}

	public static void main(String args[]) {
		for(int i=0; i<arr.length;i++)
			System.out.println("arr["+i+"] :" + arr[i]);
	}
}

💻 출력
arr[0] :9
arr[1] :9
arr[2] :8
arr[3] :6
arr[4] :8
arr[5] :10
arr[6] :7
arr[7] :7
arr[8] :7
arr[9] :2

-> 명시적 초기화를 통해 배열 arr을 생성하고, 클래스 초기화 블럭을 이용해서 배열의 각 요소들을 random()을 사용해서 임의의 값으로 채우도록 했다.
-> 이처럼 배열이나 예외처리가 필요한 초기화에서는 명시적 초기화만으로는 복잡한 초기화 작업을 할 수 없다. 이런 경우에는 추가적으로 클래스 초기화 블럭을 사용하도록 한다.





[출처] 자바의 정석 <기초편> (남궁 성 지음)

profile
멈추지 않기

0개의 댓글