[5주차 과제] 클래스
1. 클래스 정의하는 방법
2. 객체 만드는 방법 (new 키워드 이해하기)
3. 메소드 정의하는 방법
4. 생성자 정의하는 방법
5. this 키워드 이해하기
0. 객체
Object : 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중, 자신의 속성을 가지고 있고 다른 것과 구별되는 것
- 객체는 속성과 동작으로 구성
- 속성 = 필드 (field)
- 동작 = 메소드 (Method)
1. 객체의 상호작용
- 객체들은 각각 독립적으로 존재하고, 다른 객체와 서로 상호작용 하면서 동작
- 객체들 간 상호작용 수단 → 메소드
- 객체가 다른 객체의 기능을 이용하는 것 → 메소드 호출
2. 객체 간의 관계
- 객체는 개별적으로 사용될 수 있지만, 대부분 다른 객체와 관계를 맺고 있음
- 집합 관계 : 객체 중 하나는 부품, 하나는 완성품
- 사용 관계 : 객체 간의 상호작용 - 객체는 다른 객체의 메소드를 호출하여 원하는 결과를 얻어냄
- 상속 관계 : 상위 객체(종류) 를 기반으로 하위 객체(구체적인 사물) 를 생성하는 관계
3. 객체 지향 프로그래밍
-
현실 세계에서 어떤 제품을 만들 때, 부품을 먼저 개발하고 이 부품들을 하나씩 조립해서 완성된 제품을 만들 듯,
소프트웨어 개발 시에도 부품에 해당하는 객체들을 먼저 만들고, 이것들을 하나씩 조립해서 완성된 프로그램을 만드는 기법 ⇒ 객체 지향 프로그래밍 (OOP : Object Oriented Programming)
객체 지향 프로그래밍의 특징
캡슐화, 상속, 다형성
캡슐화 (Encapsulation)
- 객체의 필드, 메소드를 하나로 묶고, 실제 구현 내용을 감추는 것
- 외부 객체는 객체 내부 구조를 알지 못하며, 객체가 노출해서 제공하는 필드와 메소드만 이용할 수 있음
- 왜 캡슐화 ?
- 외부의 잘못된 사용으로 인해 객체가 손상되는 것을 방지
- 접근 제한자 (Access Modifier)를 통해 캡슐화
상속 (Inheritance)
- 상위 객체가 가지고 있는 필드와 메소드를 하위 객체에게 물려주어 하위 객체가 사용할 수 있도록 하는 것
- 상위 객체를 재사용해서 하위 객체를 쉽고 빨리 설계할 수 있도록 도와주고, 이미 잘 개발된 객체를 재사용해서 새로운 객체를 만들기 때문에 → 반복된 코드의 중복을 줄여줌
- 상위 객체의 수정으로 모든 하위 객체들의 수정 효과를 가져오므로 → 유지 보수 시간 최소화
다형성 (Polymorphism)
- 같은 타입이지만 실행 결과가 다양한 객체를 이용할 수 있는 성질
- 하나의 타입에 여러 객체를 대입함으로써 다양한 기능을 이용할 수 있도록 해줌
- 부모 클래스 또는 인터페이스의 타입 변환을 허용하여 다형성
- 부모 타입에는 모든 자식 객체가 대입될 수 있고 인터페이스 타입에는 모든 구현 객체가 대입 될 수 있음
- 다형성의 효과 → 객체의 부품화
- ex) 자동차를 설계할 때 타이어 인터페이스 타입을 적용했다면, 이 인터페이스를 구현한 실제 타이어들은 어떤 것이든 상관없이 장착 (대입)이 가능
1. 클래스 정의하는 방법
1. 클래스란
- 설계도 : 클래스 (class)
- 클래스로부터 만들어진 객체 : 인스턴스 (instance)
- 클래스로부터 객체를 만드는 과정 : 인스턴스화
2. 클래스 정의하는 방법
클래스 이름의 작성 규칙
번호 | 작성 규칙 | 예시 |
---|---|---|
1 | 하나 이상의 문자로 이루어져야 한다. | Car, SportsCar |
2 | 첫 번째 글자는 숫자가 올 수 없다. | Car, 3Car(x) |
3 | ’$’, ‘_’ 이외의 특수 문자는 사용할 수 없다. | $Car, _Car, @Car(x), #Car(x) |
4 | 자바 키워드는 사용할 수 없다. | int(x), float(x) |
-
클래스 이름이 단일 단어 → 첫 자를 대문자로, 나머지는 소문자
-
클래스 이름에 서로 다른 단어가 혼합된 경우 → 각 단어의 첫 머리 글자는 대문자로 작성
Calculator, Car, Member, ChatClient, ChatServer, Web_Browser
클래스 이름을 정했다면, 클래스이름.java
로 소스파일을 생성해야 함
-
소스 파일 역시 대소문자를 구분하므로 클래스 이름과 대소문자가 같도록 해야함
public class 클래스이름 { }
- public class 키워드는 클래스를 선언할 때 사용하며, 반드시 소문자로 작성해야 함
- 클래스 이름 뒤에는 중괄호
{}
를 붙여주는데,{
은 클래스 선언의 시작을 알려주고}
은 클래스 선언의 끝을 알려줌
Car 클래스 선언하기
public class Car {
}
- 일반적으로 소스 파일당 하나의 클래스를 선언함
3. 클래스의 구성 멤버
클래스에는 객체가 가져야 할 구성 멤버
-
필드 (Field)
-
생성자 (Constructor)
-
메소드 (Method)
public class ClassName { int fieldName; // 필드 ClassName() { ... } // 생성자 void methodName() { ... } // 메소드 }
1. 필드
- 객체의 고유 데이터, 부품 객체, 상태 정보를 저장하는 곳
- 선언 형태는 변수와 비슷함
변수
- 생성자와 메소드 내에서만 사용되고 생성자와 메소드가 실행 종료되면 자동 소멸
필드
- 생성자와 메소드 전체에서 사용되며 객체가 소멸되지 않는 한 객체와 함께 존재
필드 선언
-
클래스 중괄호 블록 어디서든 존재 가능
타입 필드 [= 초기값];
- Car 클래스 내의 필드
/* Car 클래스 필드 선언 */ public class Car { String company = "현대자동차"; String model = "그랜저"; String color = "검정"; int maxSpeed = 350; int speed; }
필드 사용
-
필드 값을 읽고, 변경하는 작업
-
클래스 내부에서 사용 -> 단순히 필드 이름으로 읽고 변경하면 됨
-
클래스 외부에서 사용할 경우, 우선적으로 클래스로부터 객체를 생성한 뒤 필드를 사용해야 함
Car myCar = new Car();
-
myCar 변수가 Car 객체를 참조하게 되면,
. 연산자
를 사용해서 speed 필드에 접근할 수 있음. 연산자
객체 접근 연산자
- 객체가 가지고 있는 필드나, 메소드를 사용하고자 할 때 사용됨
myCar.speed = 60; // Car 객체의 speed값을 60으로 변경
-
/* 외부 클래스에서 Car 필드값 읽기와 변경 */
public class CarExample {
public static void main(String[] args) {
// 객체 생성
Car myCar = new Car();
// 필드값 읽기
System.out.println("제작 회사 : " + myCar.company);
System.out.println("모델명 : " + myCar.model);
System.out.println("색깔 : " + myCar.color);
System.out.println("최고 속도 : " + myCar.maxSpeed);
System.out.println("현재 속도 : " + myCar.speed);
// 필드값 변경
myCar.speed = 60;
System.out.println("수정된 속도 : " + myCar.speed);
}
}
/* Result
제작 회사 : 현대자동차
모델명 : 그랜저
색깔 : 검정
최고 속도 : 350
현재 속도 : 0
수정된 속도 : 60
*/
2. 생성자
- new 연산자로 호출되는 특별한 중괄호 {} 블록
- 객체 생성 시 초기화를 담당
- 필드를 초기화하거나 메소드를 호출해서 객체를 사용할 준비를 함
- 메소드와 비슷하게 생겼지만, 클래스 이름으로 되어있고 리턴 타입이 없음
3. 메소드
- 객체의 동작에 해당하는 중괄호 {} 블록
- 메소드를 호출하게 되면 중괄호 블록에 있는 모든 코드들이 일괄적으로 실행됨
- 객체 간의 데이터 전달의 수단으로 사용됨
2. 객체 만드는 방법
클래스로부터 객체를 생성하는 방법
-
new 연산자 사용
new 클래스();
[출처] : 이것이 자바다 - 신용권의 Java 프로그래밍 정복 1권 p.194
new
- 클래스로부터 객체를 생성시키는 연산자
- new 연산자 뒤에는 생성자가 옴
- 생성자는
클래스()
형태를 가지고 있음 - new 연산자로 생성된 객체는 메모리 힙(heap) 영역에 생성됨
- 객체 지향에서는 메모리 내에서 생성된 객체의 위치를 모르면 객체를 사용할 수 없음
- new 연산자는 힙 영역에 객체를 생성시킨 후, 객체의 주소를 리턴하도록 되어있음
- 리턴한 주소를 참조 타입인 클래스 변수에 저장해두면, 변수를 통해 객체를 사용할 수 있음
클래스 타입으로 선언된 변수에 new 연산자가 리턴한 객체의 주소를 저장
클래스 변수;
변수 = new 클래스();
클래스 변수 선언과 객체 생성을 한 개의 실행문으로 작성
클래스 변수 = new 클래스();
new 연산자로 객체를 생성하고 리턴된 객체의 주소를 변수에 저장하여 변수가 객체를 참조
[출처] : 이것이 자바다 - 신용권의 Java 프로그래밍 정복 1권 p.194
클래스 선언부터 생성까지의 예제
/* 클래스 선언 */
public class Student {
}
/* 클래스로부터 객체 생성 */
public class StudentExample {
public static void main(String[] args) {
Student s1 = new Student();
System.out.println("s1 변수가 Student 객체를 참조합니다.");
Student s2 = new Student();
System.out.println("s2 변수가 또 다른 Student 객체를 참조합니다.")
}
}
- 예제가 실행되면 아래와 같이 메모리에 클래스 변수와 객체가 생성됨
- Student 클래스는 하나지만 new 연산자를 사용한 만큼 객체가 메모리에 생성됨
- 객체들 : Student 클래스의 인스턴스들
- 같은 클래스에서 생성되었지만 Student 객체는 자신만의 고유 데이터를 가지면서 메모리에서 활동
- s1과 s2가 참조하는 Student 객체는 완전히 독립된 서로 다른 객체
- 객체들 : Student 클래스의 인스턴스들
[출처] : 이것이 자바다 - 신용권의 Java 프로그래밍 정복 1권 p.196
3. 메소드 정의하는 방법
1. 메소드
- 객체의 동작에 해당하는 중괄호 {} 블록
- 중괄호 블록의 이름 = 메소드 이름
메소드 선언
- 선언부 (리턴타입, 메소드이름, 매개변수선언)와 실행 블록으로 구성됨
- 선언부 = 메소드 시그니처
리턴타입 메소드이름 ([매개변수선언, ... ]) {
실행할 코드를 작성하는 곳
}
리턴 타입
- 메소드가 실행 후 리턴하는 값의 타입
- 메소드는 리턴값이 있을 수도 있고 없을 수도 있음
- 메소드가 실행 후 결과를 호출한 곳에 넘겨줄 경우에는 리턴값이 있어야 함
메소드 이름
- 자바 식별자 규칙에 맞게 작성하면 됨
- 숫자로 시작하면 안되고, $와 _를 제외한 특수문자를 사용하지 말아야 한다
- 관례적으로 메소드명은 소문자로 작성한다
- 서로 다른 단어가 혼합된 이름이라면 뒤이어 오는 단어의 첫머리 글자는 대문자로 작성한다(CamelCase)
매개 변수 선언
- 매개변수 = 메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용
메소드 선언 및 호출 예제
/* 메소드 선언 */
public class Calculator {
// 메소드
void powerOn() {
System.out.println("전원을 켭니다");
}
int plus(int x, int y) {
int result = x + y;
return result;
}
double divide(int x, int y) {
double result = (double) x / (double) y;
return result;
}
void powerOff() {
System.out.println("전원을 끕니다");
}
}
/* 메소드 호출 */
public class CalculatorExample {
public static void main(String[] args) {
Calculator myCalc = new Calculator();
myCalc.powerOn();
int result1 = myCalc.plus(5,6);
System.out.println("result1 : " + result1);
byte x = 10;
byte y = 4;
double result = myCalc.divide(x,y);
System.out.println("result2 : " + result2);
myCalc.powerOff();
}
}
/*Result
전원을 켭니다
result1 : 11
result2 : 2.5
전원을 끕니다
*/
매개 변수의 수를 모를 경우 예제
- 매개 변수의 개수가 정해져있는 것이 일반적이지만, 경우에 따라 메소드 선언 시 매개 변수의 개수를 알 수 없는 경우가 있다.
- 매개 변수를 배열 타입으로 선언하여 해결한다
- 메소드 호출 시 배열을 넘겨줌으로써 배열의 항목 값들을 모두 전달할 수 있다
- 매개 변수를
...
을 사용해서 선언하여 해결한다- 메소드 호출 시 넘겨준 값의 수에 따라 자동으로 배열이 생성되고 매개값으로 사용된다.
/* 매개 변수의 수를 모를 경우 */
public class Computer {
int sum1(int[] values) {
int sum = 0;
for (int i=0;i<values.length;i++) {
sum += values[i];
}
return sum;
}
int sum2(int ... values) {
int sum = 0;
for (int i=0;i<values.length; i++) {
sum += values[i];
}
return sum;
}
}
2. Return 문
1. 리턴값이 있는 메소드
- 반드시 return 문을 사용해서 리턴값을 지정해야 함
- return문 없으면 → 컴파일 오류
- return문 실행되면 → 메소드 즉시 종료
- Return문의 return 값은 리턴 타입이거나, 리턴 타입으로 변환될 수 있어야 함
int plus(int x, int y) {
int result = x + y;
return result;
}
int plus(int x, int y) {
byte result = (byte) (x + y);
return result; }
-
return 값이 int 이지만, 메소드 내에서 byte, short, int 타입의 값이 리턴되도 상관 없음 (자동 형변환 되므로)
-
return문 이후에 실행문이 오는 경우 → Unreachable code (컴파일 오류)
int plus (int x, int y) { int result = x + y; return result; System.out.println(result); // Unreachable code }
2. 리턴값이 없는 메소드 (void)
-
void로 선언된 리턴값이 없는 메소드도 return 문을 사용 가능 → return 문 만나면 메소드 실행 강제 종료
-
Return문 예제
/* return 문 */ public class Car { // 필드 int gas; // 생성자 // 메소드 void setGas(int gas) { this.gas = gas; } boolean isLeftGas() { if (gas == 0) { System.out.println("gas가 없습니다"); return false; } else { System.out.println("gas가 있습니다"); return true; } } void run() { while (true) { if (gas > 0) { System.out.println("달립니다. (gas 잔량 : " + gas + ")"); gas -= 1; } else { System.out.println("멈춥니다. (gas 잔량 : " + gas + ")"); return; // run() 메소드 실행 강제 종료, 메소드 실행 종료 말고, while문만 나가려면 -> break문 이용하자 } } } }
/**return 문 - 사용 */ public class CarExample { public static void main(Stirng[] args) { Car myCar = new Car(); myCar.setGas(5); // Car 클래스의 setGas 메소드 호출 boolean gasState = myCar.isLeftGas(); // Car 클래스의 isLeftGas 메소드 호출 if (gasState) { System.out.println("출발합니다."); myCar.run(); } if (myCar.isLeftGas()) { // 조건식으로 메소드 호출 (isLeftGas() 메소드가 boolean을 리턴하기 때문에 가능) System.out.println("gas를 주입할 필요가 없습니다."); } else { System.out.println("gas를 주입하세요."); } } } /*Result gas가 있습니다. 출발합니다. 달립니다. (gas잔량 : 5) 달립니다. (gas잔량 : 4) 달립니다. (gas잔량 : 3) 달립니다. (gas잔량 : 2) 달립니다. (gas잔량 : 1) 멈춥니다. (gas잔량 : 0) gas가 없습니다. gas를 주입하세요. */
3. 메소드 호출
- 메소드는 클래스 내/외부의 호출에 의해 실행됨
- 클래스 내부의 다른 메소드에서 호출할 때 → 메소드 이름으로 호출
- 클래스 외부에서 호출할 때 → 클래스로부터 객체 생성 → 참조 변수를 이용해서 메소드 호출
- 객체가 존재해야 메소드도 존재하기 때문
객체 내부에서 호출 (클래스 내부에서 다른 메소드 호출)
메소드(매개값, ...); // return 값 안 받고 싶을 때의 메소드 호출
타입 변수 = 메소드(매개값, ...); // return값 받고 싶을 때의 메소드 호출
public class ClassName {
void method1(String p1, int p2) {
....
}
void method2() {
method1("홍길동", 100);
}
}
-
return 값 받는 변수는 메소드 리턴 타입과 동일하거나, 자동 타입 변환이 될 수 있어야 함
-
클래스 내부에서 메소드 호출
/* 클래스 내부에서 메소드 호출 */ public class Calculator { int plus(int x, int y) { int result = x + y; return result; } double avg(int x, int y) { double sum = plus(x, y); double result = sum / 2; return result; } void execute() { double result = avg(7,10); println("실행 결과 : " + result); } void println(String message) { System.out.println(message); } }
public class CalculatorExample { public static void main(String[] args) { Calculator myCalc = new Calculator(); myCalc.execute(); // Calculator 클래스의 execute() 메소드 실행 } } /*Result 실행 결과 : 8.5 */
객체 외부에서 호출
-
클래스로부터 객체를 생성 → 메소드 호출
- 메소드는 객체에 소속된 멤버이므로 객체가 존재하지 않으면 메소드도 존재하지 않기 때문
클래스 참조변수 = new 클래스(매개값, ...);
-
객체 생성 후, . 연산자로 메소드 호출 (. 연산자 : 객체 접근 연산자 → 객체가 가지고 있는 필드나 메소드에 접근할 때 사용됨)
참조변수.메소드(매개값,...); // 리턴값이 없거나, 있어도 리턴값을 받지 않을 경우 타입 변수 = 참조변수.메소드(매개값,...); // 리턴값이 있고, 리턴값을 받고 싶은 경우
-
클래스 외부에서 메소드 호출
/* 클래스 외부에서 메소드 호출 */ public class Car { // 필드 int speed; // 생성자 // 메소드 int getSpeed() { return speed; } void KeyTurnOn() { System.out.println("키를 돌립니다."); } void run() { for (int i=0; i<=50; i+=10) { speed += i; System.out.println("달립니다. (시속 : " + speed + "km/h)"); } } }
/*클래스 외부에서 메소드 호출 */ public class CarExample { public static void main(String[] args) { Car myCar = new Car(); myCar.KeyTurnOn(); myCar.run(); int speed = myCar.getSpeed(); System.out.println("현재 속도 : " + speed + "km/h"); } } /* Result 키를 돌립니다. 달립니다. (시속 : 10km/h) 달립니다. (시속 : 20km/h) 달립니다. (시속 : 30km/h) 달립니다. (시속 : 40km/h) 달립니다. (시속 : 50km/h) */
4. 메소드 오버로딩
Method Overloading : 클래스 내 같은 이름의 메소드를 여러 개 선언하는 것
메소드 오버로딩의 조건
- 매개 변수의 타입
- 개수
- 순서
위 3개 중 하나가 달라야 함
- 오버로딩된 메소드를 호출할 경우, JVM은 매개 변수의 타입을 보고 메소드를 선택
int plus(int x, int y) {
int result = x + y;
return result;
}
double plus(double x, double y) {
double result = x + y;
return result;
}
int x = 10;
double y = 20.3;
plus(x, y); // 어떤 메소드가 실행될까?
-
컴파일 오류가 날 것 같지만,
plus(double x, double y)
메소드가 실행됨
- 왜?
- JVM은 일차적으로 매개변수 타입을 보고 메소드를 선택
- 매개 변수의 타입이 일치하지 않을 경우, 자동 타입 변환이 가능한지를 보고 메소드 선택
- 왜?
메소드 오버로딩이 아닌 경우
-
매개 변수의 타입과 개수와 순서가 똑같을 경우, 매개변수 이름만 바꾸는 것
-
매개 변수의 타입과 개수와 순서가 똑같을 경우,
리턴 타입만 다르게 바꾸는 것
-
리턴 타입은 자바 가상 기계가 메소드를 선택할 때, 아무런 도움을 줄 수 없기 때문 → 컴파일 오류
int divide(int x, int y) {} double divide(int boonja, int boonmo) {} // 컴파일 오류
-
메소드 오버로딩의 가장 대표적인 예시 : System.out.println()
-
메소드 오버로딩 예제
/* 메소드 오버로딩 */ public class Calculator { // 정사각형의 넓이 double areaRectangle(double width) { return width * width; } // 직사각형의 넓이 double areaRectangle(double width, double height) { return width * height; } }
4. 생성자 정의하는 방법
생성자
- 객체를 생성할 때 호출되어 객체의 초기화를 담당
- 객체 초기화
- 필드를 초기화하거나, 메소드를 호출해서 객체를 사용할 준비를 함
- 생성자를 실행시키지 않고는 클래스로부터 객체를 만들 수 없음
- new 연산자에 의해 생성자가 성공적으로 실행되면 heap 영역에 객체가 생성되고 객체의 주소가 리턴됨
- 리턴된 객체의 주소는 클래스 타입 변수에 저장되어 객체에 접근할 때 이용됨
-
만약 생성자가 성공적으로 실행되지 않고 예외가 발생했다면 객체는 생성되지 않음
- new 연산자로 호출되는 특별한 중괄호 {} 블록
1. 기본 생성자
-
모든 클래스는 생성자가 반드시 존재하며, 하나 이상을 가질 수 있음
-
클래스 내부에 생성자 선언을 생략했다면, 컴파일러는 자동으로 중괄호 {} 블록 내용이 비어있는 기본 생성자를 바이트 코드에 자동 추가시킴
[public] 클래스() {}
- 클래스가 public class로 선언되면 기본 생성자에서도 public이 붙지만, 클래스가 public 없이 class로만 선언되면 기본 생성자에도 public이 붙지 않음
2. 생성자 선언
클래스 (매개변수선언, ... ) {
// 객체의 초기화 코드
}
- 메소드와 비슷한 모양을 가지고 있으나, 리턴 타입이 없고 클래스 이름과 동일함
- 생성자 블록 내부에서는 객체 초기화 코드가 작성되는데, 일반적으로 필드에 초기값을 저장하거나 메소드를 호출하여 객체 사용 전에 필요한 준비를 함
생성자 선언 및 생성자 호출하여 객체 생성 예제
/* 생성자 선언 */
public class Car {
Car (String color, int cc) {
}
}
public class CarExample {
public static void main(String[] args) {
Car myCar = new Car("검정", 3000);
// Car myCar = new Car(); // 클래스에 생성자가 명시적으로 선언되어 있으므로, 기본 생성자를 호출하여 객체를 생성할 수 없음
}
}
클래스에 생성자가 명시적으로 선언되어 있을 경우에는 반드시 선언된 생성자를 호출해서 객체를 생성해야 함
3. 생성자에서 필드 초기화
- 클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정됨
- 다른 값으로 초기화를 하고 싶다면 두 가지 방법이 있음
- 필드를 선언할 때 초기값을 준다
- 동일한 클래스로부터 생성되는 객체들은 모두 같은 데이터를 갖게 된다
- 객체 생성 시점에는 필드의 값이 모두 같다
- 생성자에서 초기값을 준다
- 객체 생성 시점에 외부에서 제공되는 다양한 값들로 초기화되어야 하는 경우 유용하다
- 필드를 선언할 때 초기값을 준다
생성자에서 필드 초기화 예제
/* 생성자에서 필드 초기화 */
public class Korean {
// 필드
String nation = "대한민국";
String name;
String ssn;
// 생성자
public Korean(String name, String ssn) {
// name = n;
// ssn = s;
// 가독성을 위해 초기화시킬 필드 이름과 매개변수명을 동일하게 사용
this.name = name;
this.ssn = ssn;
}
}
/* 객체 생성 후 필드 값 출력 */
public class KoreanExample {
public static void main(String[] args) {
Korean k1 = new Korean("박자바", "011225-1234567");
System.out.println("k1.name : " + k1.name);
System.out.println("k1.ssn : " + k1.ssn);
}
}
#5. this 키워드 이해하기
1. 인스턴스 멤버와 this
인스턴스 (instance) 멤버
- 객체(인스턴스)를 생성한 후 사용할 수 있는 필드와 메소드
- 인스턴스 필드
- 인스턴스 메소드
→ 객체를 생성하지 않고서는 사용 불가능
public class Car {
// 필드
int gas;
// 메소드
void setSpeed(int speed) { ... }
}
Car myCar = new Car();
myCar.gas = 10;
myCar.setSpeed(60);
Car yourCar = new Car();
yourCar.gas = 20;
yourCar.setSpeed(80);
[출처] : 이것이 자바다 - 신용권의 Java 프로그래밍 정복 1권 p.234
-
인스턴스 필드 : 객체마다 따로 존재
-
인스턴스 메소드 : 메소드 영역에 저장되고 공유 (객체마다 존재 X)
-
객체 외부에서 인스턴스 멤버에 접근하기 위해 참조 변수를 이용하는 것 처럼 객체 내부에서도 인스턴스 멤버에 접근 가능
-
생성자와 메소드의 매개 변수 이름이 필드와 동일한 경우,
-
this를 이용하여
- 인스턴스 멤버인 필드임을 명시
Car(String model) { this.model = model; // this로 인스턴스 멤버인 필드임을 명시 } void setModel(String model) { this.model = model; // this로 인스턴스 멤버인 필드임을 명시 }
-
-
-
인스턴스 멤버와 this 예제
/* 인스턴스 멤버와 this */ public class Car { // 필드 String model; int speed; // 생성자 Car(String model) { this.model; } // 메소드 void setSpeed(int speed) { this.speed = speed; } void run() { for (int i=10;i<=50; i+=10) { this.setSpeed(i); System,out.println(this.model + "가 달립니다. (시속 : " + this.speed + "km/h)"); } } } public class CarExample { public static void main(String[] args) { Car myCar = new Car("포르쉐"); Car yourCar = new Car("벤츠"); myCar.run(); yourCar.run(); } }
2. 다른 생성자 호출
생성자에서 다른 생성자를 호출할 때 this() 키워드를 이용
클래스 ([매개변수선언, ... ]) {
this(매개변수, ..., 값, ...); // 클래스의 다른 생성자 호출
실행문
}
this()
- 자신의 다른 생성자를 호출하는 코드
- 반드시 생성자의 첫줄에서만 허용됨
- this()의 매객밧은 호출되는 생성자의 매개 변수 타입에 맞게 제공해야 함
생성자 오버로딩에서 생기는 중복 코드 제거하는 예제
원래 생성자의 오버로딩 예제
/* 생성자의 오버로딩 */
public class Car {
// 필드
String company = "현대자동차";
String model;
String color;
int maxSpeed;
// Constructor
Car() {
}
Car(String model) {
this.model = model;
}
Car(String model, String color) {
this.model = model;
this.color = color;
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
중복 코드를 줄인 예시
/* 다른 생성자를 호출해서 중복 코드 줄이기 */
public class Car {
// 필드
String company = "현대자동차";
String model;
String color;
int maxSpeed;
Car() {}
Car(String model) {
this(model, "은색", 250);
}
Car(String model, String color) {
this(model, color, 250);
}
Car(String model, String color, int maxSpeed) {
this.model = model;
this.color = color;
this.maxSpeed = maxSpeed;
}
}
/* 객체 생성 시 생성자 선택 */
public class CarExample {
public static void main(String[] args) {
Car car1 = new Car();
System.out.println("car1.company : " + car1.company);
Car car2 = new Car("자가용");
System.out.println("car2.company : " + car2;company);
System.out.println("car2.model : " + car2.model);
Car car3 = new Car("자가용", "빨강");
System.out.println("car3.company : " + car3.company);
System.out.println("car3.model : " + car3.model);
System.out.println("car3.color : " + car3.color);
Car car4 = new Car("택시", "검정", 200);
System.out.println("car4.company : " + car4.company);
System.out.println("car4.model : " + car4.model);
System.out.println("car4.color : " + car4.color);
System.out.println("car4.maxSpeed : " + car4.maxSpeed);
}
}
/*Result
car1.company : 현대자동차
car2.company : 현대자동차
car2.model : 자가용
car3.company : 현대자동차
car3.model : 자가용
car3.color : 빨강
car4.company : 현대자동차
car4.model : 택시
car4.color : 검정
car4.maxSpeed : 200
*/
Reference
- 신용권, 『이것이 자바다』, 한빛미디어(2015), p.186 ~ p.235