이 글은 백기선님의 라이브 스터디 참여 및 학습 내용에 관한 정리한 글입니다.
클래스(class)란 객체 지향 프로그래밍에서 특정 객체를 생성하기 위한 변수 및 메소드를 정의하는 일종의 틀(그릇)이다.
예를 들어, 붕어빵을 만들기 위해서는 붕어빵을 찍어내기 위한 장비(틀)가 필요하다. 클래스는 여기서 장비에 해당되는 것이다.
클래스 정의 방법
[접근 지정자] class [클래스명] {
필드1
필드2
}
아래 코드는 위 작성 예시를 참고하여 만든 Point(점) 이라는 클래스다.
public class Point {
private int x; // x좌표
private int y; // y좌표
}
클래스를 정의했으면 이제 객체를 만들 수 있다.
여기서 객체를 생성하기 위해선 new 키워드를 알아야 한다.
new 키워드란?
객체를 생성하여 메모리(Heap영역)에 객체에 대한 정보를 저장할 공간을 할당하고 해당 공간의 주소를 반환하기 위한 키워드
다음은 main 메소드에서 위에서 정의한 Point 객체를 생성하는 예제
public static void main(String[] args) {
Point p = new Point(); // new를 통해 객체를 생성하여 p라는 참조 변수에 대입
}
위 Point 클래스에 필드들을 선언했지만 해당 필드의 접근 지정자는 private
이기 때문에 이 필드 값들을 가져오거나 값의 변화를 주기위한 getter, setter 메소드를 정의하려고 한다.
메소드 정의 방법
[접근 지정자] [return할 자료형] [메소드명]([자료형] [매개변수명]...) {}
public class Point {
private int x;
private int y;
public void setX(int x) {
this.x = x;
}
public void setY(int y) {
this.y = y;
}
public int getX() {
return x;
}
public int getY() {
return y;
}
}
메소드를 정의를 해봤다. 그런데 위 new 키워드 관련 부분에서 이상한 점이 있다. new Point()
라는 메소드를 썼는데 Point() 라는 메소드는 없네? 라고 생각할 수 있다. 겉보기에는 new 옆에 메소드가 붙은 것 처럼 보이지만 이는 메소드가 아닌 생성자라고 한다.
위 new 키워드 예시에서 사용한 new Point() 는 해당 Point 클래스의 기본(default) 생성자를 사용한 것이다. 그런데 클래스 내용에서는 생성자 관련 부분이 빠져있다.
왜냐하면 개발자가 따로 정의를 한 생성자가 없다면 컴파일 시점에서 자동으로 생성자를 생성하게 된다. 이것이 바로 기본 생성자다.
생성자 정의 방법
[접근 지정자] [클래스명]([자료형] [매개변수명] ...) {}
다음과 같이 생성자를 정의하는 것이 가능하다.
public class Point {
private int x;
private int y;
public Point() { // 기본 생성자
}
public Point(int x, int y) { // 이와 같이 생성자를 정의하면 new 호출시 필드 값 초기화가 가능하다.
this.x = x;
this.y = y;
}
}
위 예시를 통해 생성자를 정의해봤다. 그런데 이상한 점이 한가지 더 있다. 생성자가 2개다.
첫번째 기본 생성자와 두번째에 매개변수를 받아 초기화하는 생성자가 하나 더 있다.
이것이 가능한 이유는 메소드 오버로딩때문에 가능한 것이다.
오버로딩이란?
메소드의 이름이 중복이지만 메소드의 매개변수의 타입이나 매개변수를 받는 개수를 다르게 함으로써 동일한 이름의 메소드를 여러개 정의하는 것을 말한다.
예를 들어 다음과 같이 이용이 가능하다
public void init() {
System.out.println("매개 변수가 없는 메소드");
}
public void init(int a) {
System.out.println("매개 변수 a:" + a + " 가 있는 메소드");
}
public void init(String a) {
System.out.println("이와 같이 매개변수 개수가 같아도 자료형만 다르게 오버로딩이 가능");
}
public void init(int a, int b) {
System.out.println("매개 변수가 2개인 init 메소드");
}
위 Point(int x, int y) 생성자에서 처음보는 키워드가 하나 더 있었다. 바로 this
다.
이 키워드는 객체 자신을 의미한다는 키워드다.
이 키워드를 통해서 객체 자신을 가르키는 것이 가능하니 생성자나 메소드 블럭 안에서 필드명과 같은 이름을 가진 지역변수와의 scope 구분이 가능하다.
다음 예시를 보자
public class Point {
private int x;
private int y;
public Point(int x, int y) {
// 이와 같이 필드명들과 같은 이름의 매개변수를 받아도 this를 통해 구분이 가능해진 것이다.
this.x = x; // this.x는 객체 자신의 필드 x를 가르키고 이 필드에 매개변수 x를 대입
thix.y = y; // this.y는 객체 자신의 필드 y를 가르키고 이 필드에 매개변수 y를 대입
}
}