[Java Programming] 4.2 클래스와 인스턴스
객체지향 프로그래밍에서 가장 중요한 개념 : '클래스'
객체지향 프로그래밍(OOP)
- 수행 과제나 문제를 실제 세계의 객체로 표현해 사람이 알기쉽게 풀어나갈 수 있는 방법
객체
- 클래스를 변수로 만드는 것
- 객체 = 인스턴스라고 부름
- 클래스를 인스턴스로 만드는 과정 = 인스턴스화 (= '생성자 메소드'를 호출하는 것)
클래스
- 존재할 수 있는 사물을 추상화 시켜놓은 개념
- Java에서는 Reference Type 자료형에 해당됨
기술적/논리적 측면으로 보는 class
1) 기술적인 측면 : 변수와 메소드를 하나로 묶어놓은 개념
-> 자바프로그래밍 언어의 근본개념 : 모든코드는 class로 작성되어야한다!
ex) 형태는 변수로 표현한다 (멤버변수, 인스턴스 필드)
행동은 메소드로 표현한다(인스턴스메소드)
2) 논리적인 측면 : 설치류, 포유류, 조류, 어류등과 같이 공통된 형태나 행동 등으로 분류해 놓은것
ex)포유류 : 젖샘이 있다(형태), 수유를 한다(행동)
(결국, 기술적/논리적 측면 모두 같은 표현임)
실세계에 존재하는 모든 질량이 있는 사물은 : 1. 속성, 2. 기능(행동) 으로 표현이 가능함
- 속성 : 사물이 가지는 여러 특성 / 특징
ex) 자동차의 속성 : 시동여부, 속도
- 기능 : 클래스(객체)가 할수있는 기능(행동)을 말함 -> 속성에 있는 것들로만 기능 만들수 있음
ex) 자동차의 기능 : 시동버튼을 눌러 시동을 건다, 가속페달을 밟는다 등등
클래스를 만드는 이유
= reference type의 '자료형' 을 만들기 위해
ex) String grade = "A"; / Scanner keyboard = new Scanner(); / Math / Integer / Short ...등등
- 클래스 만들때 규칙 : 대문자로 시작한다
(primitive type : int short, boolean ... 등등은 소문자로 시작. 그 외의 자료형은 모두 대문자로 시작함)
클래스는 실제로 사용하기위해서는
-> Instance(클래스를 가지고 만든 변수)로 만들어야 사용가능함
ex) (Class) 표유류 -> (Insatnce) 코끼리, 사자 만든다
- reference type의 인스턴스를 만드는 방법 -
Class instance = new Class();
ex) 포유류 사자 = new 포유류();
변수 = 인스턴스 ?!
- 변수 : primitive type (int, long, boolean..)으로 만든것
- 인스턴스 : 그 외 클래스로 만든것들 : reference type으로 만든것
(단, String grade = ""; 은 예외적으로 값을 바로 할당시킬수 있음)
<클래스의 속성>
- '변수'로 정의
- 멤버변수, 인스턴스 필드 라고 부름
<클래스의 기능>
- 메소드 로 정의(= 인스턴스 메소드 라고 부름)
다양한 변수의 명칭들
변수 종류 (이름) | 사용 형태 | 의미 |
지역변수(local variable) | int score = 0; | 메소드 내부에서 정의한 변수들 |
parameter, arguments | main( String[] args ){} | 파라미터 내부에서의 변수 |
멤버변수, 인스턴스 필드 | int age; | 클래스 내부에서 만든 변수 |
- 범위 : 지역변수 < 파라미터 < 멤버변수(인스턴스 필드)
<멤버변수 대상>
- 인스턴스 메소드의 영향을 받는 변수들
- 영향을 받지않는 변수는 제거하거나 상수로 변경해야함
- 일부 멤버변수는 메소드의 실행상태를 제어하기도 함
- 멤버변수에는 값을 할당하지 않음!! (기본값이 채워지게 놔두는것 ex) int : 0, boolean : false & 인스턴스마다 다른값을 가지기 때문)
return의 의미2가지 : 1. 반환, 2. 즉시 해당 메소드 종료
한번 호출할때마다 press 만큼 속력이 추가가 됨
1. 클래스를 변수로 사용하려면, 인스턴스로 만들어야 함
ex) new Car(); // Car 클래스를 인스턴스로 생성
2. 인스턴스가 만들어지면 변수에 할당해야 사용할 수 있음
ex) Car car = new Car(); // 인스턴스를 만들어 Car 타입의 car 변수에 할당
3. Reference Type의 변수는 “인스턴스"라고 부름
ex) Car 클래스는 Reference Type이므로 car 변수는 인스턴스입니다
4. Reference Type의 인스턴스는 Primitive Type에는 없는 특별한 점 연산자 (“ . ” )를 사용할 수 있음
ex)car.pressEngineStartButton(); -> car 인스턴스의 pressEngineStartButton 메소드를 실행하라고 하는 명령
Reference Type?
- “메모리 참조타입” 을 말함
- 여러 변수들의 메모리 공간을 종류별로 묶어 그 주소를 참조
- 연속해서 쓰여져 있다
Primitive Type vs Reference Type
Primitive Type | Reference Type |
항상 값을 참조 | 항상 메모리 주소 (메모리 묶음) 를 참조 |
숫자 | 문자열 |
문자 (한글자) | 배열 |
true / false | primitive type을 제외한 모든것 |
정해진 Byte 크기만큼 메모리 할당 | 하나의 메모리로 사용할수 없음(여러개 메소드를 사용하므로) |
인형뽑기게임 흉내내기 예제
insertCoin()
- 인형뽑기 기계에 동전을 넣습니다.
- 동전을 넣지 않으면 doGame()은 실행되지 않아야 합니다.
- 동전을 넣으면 isInsertCoin 변수는 true가 되어야 합니다.
- dolls의 값이 0보다 작거나 같을 경우 isInsertCoin은 true로 변하지 않습니다.
doGame()
- isInsertCoin이 true 일 때 만 게임을 진행합니다. (아니면 return)
- 만약, 인형을 뽑았다면 1을 반환하고
- 뽑지 못했다면 0을 반환합니다.
- 반환하는 숫자는 랜덤하게 선정합니다. (math.random())
- 1을 반환했을 경우, dolls 변수에서 1을 빼야합니다.
- 값을 반환하기 직전에 isInsertCoin을 false로 변경해야 합니다. (게임을 또 할려면 또 코인을 넣어야 하므로)
package Hello.java;
public class DollClawMachine {
boolean isInsertCoin;
int dolls;
public void isInsertCoin() {
if (dolls > 0) {
isInsertCoin = true;
}
}
public int doGame() {
if (isInsertCoin) {
// Math.random()으로 0,1중 하나 랜덤하게 생성
double randomNumber = Math.random();
int result = (int) ((randomNumber * 10) % 2);
if (result == 1) {
System.out.println("인형을 뽑았습니다.");
// 만약 인형을 뽑았을경우(result =1) dolls -1 해줌 (전체인형개수에서 빼주는것)
dolls -= result;
isInsertCoin = false;
return result;
}
else {
System.out.println("인형을 뽑지 못했습니다.");
isInsertCoin = false;
return 0;
}
}
return 0;
}
public static void main(String[] args) {
DollClawMachine game = new DollClawMachine();
game.isInsertCoin = true;
game.dolls = 5;
game.isInsertCoin();
int result = game.doGame();
System.out.println("남은 인형 개수는 : " + game.dolls + "개 입니다.");
System.out.println("뽑은 인형 개수는 : " + result + "개 입니다.");
}
}
Math 클래스
- java.lang.Math클래스는 수학 계산에 사용할수있는 메소드(static) 제공함 -> 정적(static)이기때문에 바로사용 가능
메소드 | 설명 | 예제 | 리턴값 |
int abs(int a) ->double도 가능 |
절대값 | int v1 = Math.abs(-1); | v1 = 1 |
double ceil(double a) | 올림값 | double v2 = Math.ceil(5.3); | v2 = 6.0 |
doule floor(double a) | 버림값 | double v3 = Math.floor(-5.3); | v3 = -6.0 |
int max(int a, int b) ->double도 가능 |
최대값 | int v4 = Math.max(5, 9); | v4 = 9 |
int min(int a, int b) ->double도 가능 |
최소값 | int v5 = Math.min(5, 9); | v5 = 5 |
double random() | 랜덤값 | double v6 = Math.random(); | 0.0 <= v6 < 1.0 |
double rint(double a) | 가까운정수의 실수값 | double v7 = Math.rint(5.7); | v7 = 6.0 |
long round(double a) | 반올림값 | long v14 = Math.round(5.3); | v14 = 5 |
*Math.random()*
- 0.0 (포함) ~ 1.0(미포함) 범위에 속하는 하나의 double타입 값 리턴
- Math.random()을 이용해서 1~10까지의 난수를 얻는 과정
1. 각변에 10을 곱한다 -> 0.0 <= Math.random() * 10 < 10.0 범위의 double타입 값 얻음
2. 각 변을 int타입으로 강제 형변환 -> 0 <= (int) Math.random() * 10 < 10 범위의 하나의 int값
3. 각 변에 +1 -> 1 <= (int)Math.random() * 10 + 1 < 11 범위의 정수
*Math.round()*
- 소수점 첫째자리에서 반올림해서 정수값 리턴
- 원하는 소수 자릿수에서 반올림된 값 얻기 위해서는 : 반올림할 자릿수가 소수점 첫째자리가 되도록 10(n승) 을 계속 곱해주고 -> round() 메소드의 리턴값을 얻은 후 -> 다시 10(n승).0 을 나눠주면 됨