package oop;
import java.util.Random;
public class Ex02 {
public static void main(String[] args) {
// oop.Number 클래스 (Ex01)를 사용하여 객체의 배열 생성
Number[] arr = new Number[12];
// 배열(Number를 저장할 수 있는 참조변수 12개)만 생성했을 뿐,
// Number타입의 객체(실체)는 아직 없다
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
} // 모든 칸이 비어있다
for(int i = 0; i < arr.length; i++) {
arr[i] = new Number(i + 100);
} // 각 칸에 i + 1값으로 객체를 생성한다
for(int i = 0; i < arr.length; i++) {
System.out.println(arr[i]);
} // 모든 칸이 비어있지 않다
Random ran = new Random();
int n = ran.nextInt(12); // 정수를 랜덤으로 지정하여
Number cpu = arr[n]; // 컴퓨터가 n번째 카드를 뽑게 한다
int m = ran.nextInt(12);
Number you = arr[m];
System.out.printf("cpu : %s, you : %s\n", cpu, you);
System.out.println(cpu.num > you.num ? "패배" : "승리");
}
}
아래 코드를 보면 매개 변수를 전달 받지 않는 생성자 Circle( ) 의 첫째 줄에 this( 3 . 0 )이 들어가 있는 것을 볼 수 있는데, 생성자 내부에서 또 다른 생성자를 호출할 수 있음을 보여주고 있다. 실수 ( double )인 3.0을 입력받고 있기에 매개변수로 실수형을 받고 있는 3번째 생성자가 실행된다. 마찬가지로 int를 받아오는 2번째 생성자도 double 강제 형변환을 이용하여 3번째 생성자에게 값을 넘겨주고 있다. 매우 중요한 내용이므로 절대 까먹지 않게 주의하자
package oop;
class Circle {
double radius; // 반지름
double pi = 3.14; // 클래스의 멤버 필드는 초기값을 미리 지정할 수 있다
double area; // 원의 넓이 (반지름 x 반지름 x 3.14) cm²
double length; // 원의 둘레 (반지름 x 2 x 3.14) cm
// 생성자 : 객체를 생성하는 메서드(method:방식)
// 생성자 오버로딩 : 객체를 생성하는 여러 방식을 제공하겠다
// 생성자 내부에서 또다른 생성자를 호출하려면, 항상 첫번째줄에서만 가능하다
// 1) 반지름을 전달받지 않으면, 기본값 3을 적용한다
Circle() {
// Circle(3.0); // 생성자 내부에서 또다른 생성자를 호출할 때는 this키워드를 사용한다
this(3.0); // 항상 생성자 코드의 첫줄에서만 가능 !!
// radius = 3;
// area = radius * radius * pi;
// length = radius * 2 * pi;
}
// 2) 반지름을 정수로 전달받으면, 생성자에서 둘레와 면적을 계산하여 저장한다
Circle(int radius) {
this((double)radius);
// this.radius = radius;
// area = radius * radius * pi;
// length = radius * 2 * pi;
}
// 3) 반지름을 실수로 전달받으면, 생성자에서 둘레와 면적을 계산하여 저장한다
Circle(double radius) {
this.radius = radius;
area = radius * radius * pi;
length = radius * 2 * pi;
}
void show() {
System.out.printf("반지름 : %.2fcm\n", radius);
System.out.printf("원의 넓이 : %.2fcm²\n", area);
System.out.printf("원의 둘레 : %.2fcm\n", length);
System.out.println();
}
}
public class Ex04 {
public static void main(String[] args) {
Circle ob1 = new Circle();
Circle ob2 = new Circle(4);
Circle ob3 = new Circle(2.4);
ob1.show();
ob2.show();
ob3.show();
}
}
아래의 코드를 실행했을 경우 결과는
int 를 전달받는 생성자 호출 !!
기본 생성자 호출!!
int를 전달받는 생성자 호출 !!
순서로 나오게 된다.
this를 이용하여 생성자를 호출했을 경우 일반적인 함수 같이 다른 생성자의 내부 실행이 모두 끝나야 나머지 코드가 실행된다.
package oop;
class Test2 {
int num;
// 기본 생성자
Test2() {
this(0);
System.out.println("기본 생성자 호출 !!");
// Constructor call must be the first statement in a constructor
// 1) 객체의 생성 (생성이 완료되지 않으면, 추가작업을 진행할 수 없다)
// 2) 객체의 생성 이후 초기값 할당 및 추가 작업 진행
}
Test2(int num) {
this.num = num;
System.out.println("int 를 전달받는 생성자 호출 !!");
}
}
public class Ex05 {
public static void main(String[] args) {
Test2 ob1 = new Test2();
Test2 ob2 = new Test2(12);
}
}
아래 코드를 해석해보면 int count에 static 키워드를 붙혀 사용하고 있다. 클래스.필드를 이용하여 접근하는 것이 가장 이상적이며, 객체.필드를 이용하여 접근이 가능하긴 하나, 그렇게 되면 static필드를 굳이 사용할 필요성이 없어진다. 그냥 정적필드는 클래스.필드 형식으로 무조건 접근해야 한다고 생각하는 것이 옳다.
package oop;
class Human {
String name;
int age;
static int count;
Human(String name, int age) {
this.name = name;
this.age = age;
count++;
System.out.println(name + " 객체를 생성했습니다 !!");
}
void show() {
System.out.printf("%s : %d살\n", name, age);
}
}
public class Ex06 {
public static void main(String[] args) {
System.out.println("Human.count : " + Human.count);
Human ob1 = new Human("이지은", 30);
Human ob2 = new Human("홍진호", 41);
ob1.show();
ob2.show();
System.out.println("Human.count : " + Human.count);
System.out.println("ob1.count : " + ob1.count);
System.out.println("ob2.count : " + ob2.count);
ob1.count++; // 첫번째 객체의 count를 증가시키면
System.out.println("ob2.count : " + ob2.count); // 두번째 객체의 count가 증가되어있다
// The static field Human.count should be accessed in a static way
// Human클래스의 count필드는 정적필드이므로, 정적인 방법으로 접근해야 합니다
// 다시 말해, 객체.필드 방식이 아니라, 클래스.필드로 접근하는 것이 올바른 방법입니다
}
}