클래스에는 객체가 가져야할 구성 멤버가 선언된다.
필드(Field)
생성자(Constructor)
메소드(Method)
이 구성 멤버들은 생략되거나 복수 개가 작성될 수 있다.
필드(Field)
객체의 고유 데이터, 부품 객체, 상태 정보를 저장하는 곳
선언된 형태는 변수와 비슷하지만, 필드를 변수라 부르지는 않음
변수는 생성자와 메소드 내에서만 사용, 생성자와 메소드가 실행 종료되면 자동 소멸
필드는 생성자와 메소드 전체에서 사용되며, 객체가 소멸되지 않는 한 객체와 함께 존재
생성자(Constructor)
new 연산자로 호출되는 특별한 중괄호 {} 블록
객체 생성 시 초기화를 담당 (필드를 초기화하거나, 메소드를 호출해서 객체를 사용할 준비를 한다)
메소드와 비슷하게 생겼지만, 클래스 이름으로 되어있고, 반환 타입이 없다.
메소드(Method)
객체의 동장에 해당하는 중괄호 {} 블록
중괄호 블록은 이름을 가지고 있는데 , 이것이 메소드 이름
메소드를 호출하게 되면 중괄호 블록의 모든 코드들이 일괄적으로 실행
메소드는 필드를 읽고 수정하는 역할도 하지만 다른 객체를 생성해서 다양한 기능을 수행
메소드는 객체 간의 데이터 전달 수단으로 사용
외부로부터 매개값을 받을 수 있고, 실행 후 어떤 값을 반환할 수도 있다.
필드 선언
필드 선언은 중괄호 블록 어디서든 존재할 수 있다.
생성자 선언과 메소드 선언의 앞, 뒤 어디서든 필드 선언이 가능
하지만 생성자와 메소드 중괄호 블록 내부에는 선언될 수 없다.
생성자와 메소드 중괄호 내부에 선언된 것은 모두 로컬 변수가 된다.(필드 X)
필드 선언의 변수의 선언 형태와 비슷 (클래스 멤버 변수로 부르기도 함)
타입 필드 [= 초기값];
ex)
String car = "Sonata";
int maxSpeed = 200;
int currentSpeed;
boolean enginStart;
만약 초기값이 지정되지 않은 필드들은 객체 생성 시 자동으로 기본 초기값으로 설정
필드 사용
필드를 사용하는 것은 필드값을 읽고, 변경하는 작업
클래스 내부의 생성자나 메소드에서 사용할 경우 단순히 필드 이름을 읽고 변경하면 되지만,
클래스 외부에서 사용할 경우 우선적으로 클래스로부터 객체를 생성한 뒤 필드를 사용
필드는 객체에 소속된 데이터이므로 객체가 존재하지 않으면 필드도 존재하지 않기 때문
Car 클래스의 speed 필드는 생성자와 메소드에서 변경이 가능 (사용 방법이 변수와 동일)
변수는 자신이 선언된 생성자 또는 메소드 블록 내부에서만 사용할 수 있는 반면(지역 변수)
필드는 생성자와 모든 메소드에서 사용 가능(전역 변수)
외부 Person 클래스에서 Car 클래스의 speed 필드값을 사용하려면, Car 객체를 우선 생성해야함
Car myCar = new Car();
myCar 변수가 Car 객체를 참조하게 되면 도트 ( . ) 연산자로 speed 필드에 접근 가능
도트 ( . ) 연산자는 객체 접근 연산자로 객체가 가지고 있는 필드, 메소드를 사용하고자 할 때 사용
myCar.speed = 60;
기본 생성자
모든 클래스는 생성자가 반드시 존재하며, 하나 이상을 가질 수 있다.
클래스 내부에 생성자 선언을 생략했다면, 컴파일러는 아래와 같이 중괄호{} 블록 내용이 비어있는
기본 생성자(Default Constructor)를 바이트 코드에 자동 추가시킨다.
[public] 클래스() {}
클래스가 public class로 선언되면 기본 생성자에도 public이 붙지만,
클래스가 public 없이 class 로만 선언되면, 기본 생성자에도 public이 붙지 않는다.
따라서 클래스에 생성자를 선언하지 않아도, 아래와 같이 new 연산자 뒤에 기본 생성자를 호출해서
객체를 생성시킬 수 있다.
Car myCar = new Car(); // Car() : 기본 생성자
클래스에 명시적으로 선언한 생성자가 한 개라도 존재하면, 컴파일러는 기본 생성자를 추가하지 않는다.
명시적으로 생성자를 선언하는 이유는 객체를 다양하게 초기화 하기 위해서.
생성자 선언 (생성자 명시)
기본 생성자가 아닌 생성자를 명시적으로 선언
클래스 (매개변수 선언, . . .){ //생성자 블록
// 객체의 초기화 코드
}
매개 변수 선언은 생략 가능, 여러개 선언도 가능
매개변수는 new 연산자로 생성자 호출 시 외부의 값을 생성자 블록 내부로 전달하는 역할을 한다.
Car myCar = new Car("그랜저", "검정", 300);
String, String, int 타입 ( Car 생성자를 호출 시 3개의 값을 제공)
3 개의 매개 값을 생성자가 받기 위해 아래와 같이 생성자를 선언
public class Car{
//생성자
Car(String model, String color, int maxSpeed){
...
}
}
클래스 생성자가 명시적으로 선언되었을 경우, 반드시 선언된 생성자를 호출해서 객체를 생성해야만 한다.
필드 초기화
클래스로부터 객체가 생성될 때 필드는 기본 초기값으로 자동 설정
만약 다른값으로 초기화 하고 싶으면
- 필드를 선언할 때 초기값을 준다
- 생성자에서 초기값을 준다(매개 변수)
필드를 선언할 때 초기값을 주게 되면, 동일한 클래스로부터 생성되는 객체들은 모두 같은 데이터를 갖게 된다.
객체 생성 후 변경할 수 있지만, 객체 생성 시점에는 필드 값이 모두 같다.
객체 생성 시점에서 외부에서 제공되는 다양한 값들로 초기화 되어야 한다면 생성자에서 초기화를 해야 한다.
필드 값은 클래스를 작성할 때 초기값을 줄 수 없고 객체 생성 시점에 다양한 값을 가져야 한다.
따라서 생성자의 매개값으로 이 값들을 받아 초기화 해야한다.
관례적으로 필드와 동일한 이름을 갖는 매개 변수를 사용
하지만 필드와 매개변수의 이름이 동일할 경우, 생성자 내부에서 해당 필드에 접근할 수 없다.
동일한 이름의 매개변수가 사용 우선순위가 높기 때문이다.
이럴 때는 필드 앞 "this."를 붙이면 된다.
this는 객체 자신의 참조이고, 자신을 "나" 라고 하듯 객체가 객체 자신을 this라고 칭한다.
publie class Car{
//필드
String company = "현대자동차"
String name;
String model;
public Car(String name, String model){ //생성자의 매개변수가 필드와 동일한 경우 매개변수 우선
this.name = name; //this.name (필드), name(매개변수)
this.model = model; //this.model (필드), model(매개변수)
}
객체의 필드는 하나가 아니라 여러 개가 있고, 이 필드들을 모두 생성자에서 초기화 한다면
생성자의 매개 변수의 수는 필드 수만큼 선언되야 한다.
실제로는 중요한 몇개의 필드만 매개 변수를 통해 초기화, 나머지 필드들은 필드 선언시 초기화 하거나,
생성자 내부에서 임의의 값 또는 계산된 값으로 초기화
또는, 객체 생성 후에 필드값을 별도로 저장하기도 한다.
생성자 오버로딩(Overloading)
외부에서 제공되는 다양한 데이터들을 이용해서 객체를 초기화 하려면,
생성자도 다양화 될 필요가 있다.
Car 객체를 생성 시 외부에서 제공되는 데이터가 없다면, 생성자로 Car 객체를 생성해야 하고,
외부에서 model, color 데이터를 제공될 경우, Car 객체를 생성할 수 있어야 한다.
따라서 생성자가 하나뿐이라면, 두 가지 경우에 따라 객체를 모두 생성할 수 없다.
생성자 오버로딩 : 매개 변수를 달리하는 생성자를 여러 개 선언이 가능하도록 하는 것.
public class 클래스{
클래스 ( [타입 매개변수1, 타입 매개변수2, . . .] ){ //생성자 1
. . .
}
클래스 ( [타입 매개변수1, 타입 매개변수2, . . .] ){ //생성자 2
. . .
}
}
Car 클래스 에서의 생성자 오버로딩
public class Car {
Car() { . . .}
Car(String model) { . . .}
Car(String model, String color) { . . .}
Car(String model, String color, int maxSpeed) { . . .}
}
생성자 오버로딩 시 주의할 점
매개 변수의 타입과 개수, 선언된 순서가 똑같을 경우
매개 변수 이름만 바꾸는 것은 생성자 오버로딩으로 볼 수 없다.(구분 불가)
Car(String model, String color) { . . .}
Car(String color, String model) { . . .} //오버로딩 X
생성자가 오버로딩 되어 있는 경우, new 연산자로 생성자를 호출할 때
제공되는 매개값의 타입과 개수에 의해 호출될 생성자가 결정
메소드 선언
선언부 (반환타입, 메소드 이름, 매개 변수 선언) 와 실행 블록으로 구성
메소드 선언부를 "메소드 시그니처" 라고도 한다.
메소드 선언 형태
반환 타입 (return)
메소드가 실행 후 반환하는 값의 타입을 의미( 반환값이 있을수도, 없을수도 있음)
메소드가 실행 후 결과를 호출한 곳에 넘겨줄 경우, 반환값이 있어야 한다.
반환값이 없는 메소드는 반환 타입에 void가 와야하며,
반환값이 있는 메소드는 반환값의 타입이 와야한다.
void powerOn() { . . .} //전원을 켜는 메소드는 반환값이 없어도 된다.
double divide(int x, int y) { . . .} //나눗셈 후 결과값을 반환해야 한다.
아래와 같이 호출할 수 있다.
powerOn(); // 반환값, 매개변수 없이 메소드만 호출
double result = divide(10, 20); // 매개변수 10을 20으로 나눈 나머지 0.5가 반환되어 저장
divide 메소드는 double 타입으로 반환하기 때문에 int 타입으로 result 변수를 선언하게 되면 컴파일 에러가 발생
반환값에 반드시 변수를 저장할 필요는 없다.
메소드 이름
자바 식별자 규칙에 맞게 작성해야 한다
- 숫자로 시작할 수 없고 $,_ 를 제외한 특수 문자는 사용할 수 없다.
- 관례적으로 메소드 명은 소문자로 시작한다.
- 서로 다른 단어가 혼합된 이름일 때, 단어의 첫 머리 글자는 대문자로 작성한다.
ex) void run() { . . .} , String getName() { . . .}
어떤 기능을 수행하는지 알 수 있도록 이름을 지어준다.
매개 변수 선언
메소드가 실행할 때 필요한 데이터를 외부로부터 받기 위해 사용
매개 변수도 필요할 수도, 없을수도 있다.
만약 타입이 잘못된 매개 변수 값을 넘겨주게 되면 컴파일 에러가 발생(자동 타입 변환이 되는 경우는 예외)
ex) Calculator.java 클래스
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("전원을 끕니다.");
}
}
CalculatorExample.java : 메소드 호출
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); //11
byte x = 10;
byte y = 4;
double result2 = myCalc.divide(x, y);
System.out.println("result2 : " + result2); //2.5
myCalc.powerOff(); //전원을 끕니다.
}
}
리턴(return) 문
반환값이 있는 메소드
메소드 선언에 리턴 타입이 있는 메소드는 반드시 리턴(return) 문을 사용해서 리턴 값을 지정해야 한다.
return 문이 없다면 컴파일 에러가 발생
return 문이 실행되면 메소드는 이후 즉시 종료
return 리턴값;
return 문의 리턴값은 리턴 타입이거나, 리턴 타입으로 변환될 수 있어야 한다.
int plus(int x, int y){
int result = x + y;
return result;
}
하지만 if문으로 실행문이 분기되는 경우는 컴파일 에러가 발생하지 않는다.
int plus(int x, int y){
byte result = (byte)(x + y);
return result; //inr 타입으로 자동 변환된다.
}
리턴값이 없는 메소드(void)
void로 선언된 리턴값이 없는 메소드에서도 return문을 사용할 수 있다.
return 문을 사용하게 되면 메소드 실행을 강제 종료시킨다.
return;
메소드 호출
메소드는 클래스 내부, 외부의 호출에 의해 실행
클래스 내부의 다른 메소드에서 호출할 경우, 단순히 메소드 이름으로 호출하면 되지만,
클래스 외부에서 메소드를 호출할 경우, 우선 클래스로부터 객체를 생성한 뒤,
참조 변수를 이용해서 메소드를 호출해야 한다.
(객체가 존재해야 메소드도 존재하기 때문)
클래스 내부에서 메소드 호출 (객체 내부)
클래스 내부에서 메소드를 호출하려면 아래와 같이 작성
메소드가 매개 변수를 가지고 있을 때, 매개 변수의 타입과 수에 맞게 매개값을 제공한다.
메소드( 매개값1, . . .);
- 호출에서 method1( "홍길동", 100)이 호출되면 매개값인 "홍길동"은 p1 매개 변수에 대입, 100은 p2 매개 변수에 대입
- 실행에서 p1, p2 변수를 이용
메소드가 리턴값이 없거나, 있어도 받고 싶지 않을 경우 위와 같이 모두 호출이 가능
리턴값이 있는 메소드를 호출하고 리턴값을 받고 싶다면, 아래와 같이 변수를 선언하고 리턴값을 저장
타입 변수 = 메소드( 매개값1, . . .); // 메소드의 리턴값을 변수에 저장한다
변수 타입은 메소드 리턴 타입과 동일해야 하거나, 자동 타입 변환(큰 자료형으로)이 될 수 있어야 한다.
클래스 외부에서 메소드 호출 (객체 외부)
외부 클래스에서 메소드를 호출하려면, 아래와 같이 우선 클래스로부터 객체를 생성
메소드는 객체에 소속된 멤버이므로, 객체가 존재하지 않으면, 메소드도 존재하지 않는다.
클래스 참조변수 = new 클래스(매개값1, 매개값2, . . .); //객체 생성
객체가 생성되었다면, 참조 변수와 함께 도트 ( . ) 연산자로 메소드를 호출할 수 있다.
도트 ( . ) 연산자는 객체 접근 연산자로 객체의 필드, 메소드에 접근할 때 사용
참조변수.메소드(매개값1, 매개값2, . . .); //리턴값이 없거나, 있어도 리턴값을 받지 않을 경우
타입 변수 = 참조변수.메소드(매개값1, 매개값2, . . .); //리턴값이 있고, 리턴값을 저장할 경우
참고블로그
'Java > Java' 카테고리의 다른 글
[Java]public static void (0) | 2022.11.27 |
---|---|
[Java]오버라이딩 (Override) (0) | 2022.11.27 |
[Java] 클래스 선언 (0) | 2022.11.22 |
Object-Oriented Programming(OOP) (0) | 2022.11.22 |
[Java] 정규표현식(Regular Expression) (0) | 2022.11.20 |
댓글