국비 수업 10일차

김성수·2022년 10월 31일
0
post-thumbnail

1. Random 함수를 이용한 간단한 게임

  1. 랜덤 함수 선언 ( java.util.Random )
  2. 원하는 크기의 공간을 생성하여 숫자를 채워준다.
  3. 배열에 접근할 두개의 랜덤 수를 뽑아 배열 내부의 값을 서로 비교한 후 승리 여부를 출력한다.
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 ? "패배" : "승리");
		
		
	}
}

2. 클래스의 객체를 생성하는 생성자에 대하여

  • 생성자 : 지정한 클래스의 객체를 생성하는 특수한 함수

  • 생성자는 함수를 기반으로 구성되어 있기에 오버로딩이 가능하다

  • 생성자를 따로 작성하지 않으면, 컴파일 시 기본 생성자를 자동으로 만들어준다
    ( 이때, 기본 생성자란 매개변수를 전달받지 않는 생성자를 말한다. )

  • ※ 여기가 가장 중요) 생성자는 반드시 클래스의 이름과 동일해야한다.

  • 별도의 반환형을 가지지 않는다 (void도 쓰지 않는다)

3. 생성자의 오버로딩과 this키워드를 이용한 실행 구조

아래 코드를 보면 매개 변수를 전달 받지 않는 생성자 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();
	}
}

4. 생성자의 실행 순서

아래의 코드를 실행했을 경우 결과는

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);
	}
}

5. 정적 멤버 요소를 만드는 static에 대하여

  • static : 정적 멤버 요소를 만들때 사용한다
  • 특정 객체를 지목하지 않아도, 자료형에 각인되어 있는 속성이나 기능을 만들 수 있다
  • ※ 중요 ) 객체를 생성하지 않아도, 클래스로 접근이 가능하다
  • ※ 중요 ) 같은 클래스를 사용하는 모든 객체가 공유할 수 있다
  • 클래스 : 객체를 생성하기 위한 자료형, 설계도와 같은 역할
  • 객체 : 클래스에 의해 만들어진 실체, 객체를 통하여 속성이나 기능에 접근할 수 있다

아래 코드를 해석해보면 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필드는 정적필드이므로, 정적인 방법으로 접근해야 합니다
//		다시 말해, 객체.필드 방식이 아니라, 클래스.필드로 접근하는 것이 올바른 방법입니다
		
	}
}
profile
다들 잘하는데 나만 못해?

0개의 댓글