학습목표
1. 객체 생성을 위한 클래스의 선언
2. 필드를 선언하고 생성 후, 이를 읽어들이거나 변경하는 방법
3. 생성자를 선언하고 생성자에서 필드를 초기화
4. 메소드의 다양한 기능 이해
5. 패키지 선언하는 방법
6. 접근 제한자의 종류와 사용 방법
메소드 선언 : 선언부, 실행 블록으로 구성된다.
int sum1(int[] values) { }
int sum2(int ... values) {}
메소드 선언에 리턴 타입이 있는 메소드는 반드시 리턴문을 사용해서 리턴값을 지정해야 한다.
return문의 리턴값은 리턴 타입이거나 리턴 타입으로 변환될 수 있어야 한다.
ex) int인 plus()메소드 - byte, short, int값이 리턴되어도 상관없음 => byte와 short는 int로 자동타입 변환되어 리턴되기 때문에
return 리턴값;
리턴값이 없는 메소드는 리턴 타입으로 void를 사용한다.
void로 선언된 메소드에서도 return문 사용할 수 있다! => 리턴값을 지정하는 것이 아니라, 메소드 실행을 강제 종료시키는 역할을 한다.
return
메소드는 클래스 내/외부의 호출에 의해 실행된다.
클래스 외부에서 호출할 경우 : 우선 클래스로부터 객체를 생성한 뒤 참조변수를 이용해서 메소드를 호출해야 한다. (객체가 존재해야 메소드도 존재하기 때문)
리턴값이 있는 메소드를 호출하고 리턴값을 받고 싶다면 다음과 같이 변수 선언
타입 변수 = 메소드(매개값, ...);
void method1(String p1, int p2){ }
우선, 클래스로부터 객체를 생성해야한다. 메소드는 객체에 소속된 멤버이므로 객체가 존재하지 않으면 메소드도 존재하지 않기 때문!
클래스 참조변수 = new 클래스(매개값, ...);
Car myCar = new Car();
객체가 생성되었다면 참조 변수와 함께 도트(.)연사자를 사용해서 메소르를 호출할 수 있다.
참조변수.메소드(매개값, ...); // 리턴값이 없거나, 있어도 리턴값을 받지 않을 경우
myCar.run();
타입 변수 = 참조변수.메소드(매개값, ...); // 리턴값이 있고, 리턴값을 받고 싶을 경우
int speed = myCar.getSpeed();
메소드 오버로딩 : 클래스 내에 같은 이름의 메소드를 여러 개 선언하는 것
(오버오딩: 많이 싣는것 => 하나의 메소드 이름으로 여러기능을 담는다하여 붙여진 이름)
조건 : 매개변수의 타입, 개수, 순서 중 하나가 달라야 한다는 점
필요 이유 : 매개값을 다양하게 받아 처리할 수 있도록 하기 위해서
public class Calculator{
// 정사각형의 넓이
double areaRectangle(double width){
return width * width;
}
// 직사각형의 넓이
double arearectangle(double width, double height){
return width * height;
}
}
public class CalculatorExample{
public static void main(String[] args){
Calculator myCalcu = new Calculator();
//정사각형의 넓이 구하기
double result1 = myCalcu.areaRectangle(10);
// 직사각형의 넓이 구하기
double result2 = myCalcu.areaRectangle(10, 20);
}
}
인스턴스 멤버 : 객체마다 가지고 있는 멤버, 객체(인스턴스) 생성한 후 사용할 수 있는 필드와 메소드
정적 멤버 : 클래스에 위치시키고 객체들이 공유하는 멤버
this : 생성자와 메소드의 매개 변수 이름이 필드와 동일한 경우, 인스턴스 멤버인 필드임을 명시하고자 할 때 사용된다.
Car(String model){
this.model = model;
}
void setModel(String model){
this.model = model;
}
정적 : 고정된이란 의미
정적 멤버 : 클래스에 고정된 멤버로서 객체를 생성하지 않고 사용할 수 있는 필드와 메소드를 말한다.
정적 멤버 선언: 필드와 메소드 선언시 static키워드 추가적으로 붙이면 된다.
정적 메소드 선언할때 : 이들 내부에 인스턴스 필드나 인스턴스 메소드를 사용할 수 없다. 객체 자신의 참조인 this키워드도 사용이 불가능
=> 인스턴스 멤버 사용하고 싶다면? 객체를 먼저 생성하고 참조 변수로 접근해야 한다.
static void method3(){
ClassName obj = new ClassName();
obj.field1 = 10;
obj.method1();
}
싱글톤Singleton : 전체 프로그램에서 단 하나의 객체만 만들도록 보장해야 하는 경우
public class 클래스{
// 정적 필드
private static 클래스 singleton = new 클래스();
// 생성자
private 클래스(){ }
// 정적 메소드
static 클래스 getInstance(){
return singleton;
}
}
final필드 : 초기값이 저장되면 이것이 최종적인 값이 되어서 프로그램 실행 도중에 수정할 수 없는 필드. final키워드로 선언
상수 : 불변의 값을 저장하는 필드. final static 키워드로 선언
public : 모든 패키지에서 아무런 제한 없이 필드와 메소드를 사용할 수 있도록 해준다.
protected :같은 패키지에 속하는 클래스에서 필드와 메소드를 사용할 수 있도록 한다. 다른 패키지에 속한 클래스가 해당 클래스의 자식 클래스라면 필드와 메소드를 사용할 수 있다.
default : 같은 패키지에서는 아무런 제한 없이 필드와 메소드를 사용할 수 있으나, 다른 패키지에서는 필드와 메소드를 사용할 수 없도록 한다.
private : 동일한 패키지이건 다른 패키지이건 상관없이 필드와 메소드를 사용하지 못하도록 제한한다. 오로지 클래스 내부에서만 사용할 수 있다.
객체 지향 프로그래밍에서는 객체의 필드를 객체 외부에서 직접적으로 접근하는 것을 막는다. 이유는 외부에서 마음대로 변경할 경우 객체의 무결성이 깨질 수 있기 때문.