클래스 정의하는 방법
■ 클래스란?
- 객체를 정의하는 틀 또는 설계도와 같은 의미
- Java에서는 이러한 클래스를 가지고, 여러 객체를 생성하여 사용
■ 구성
- 생성자, 객체의 상태를 나타내는 필드와 객체의 행동을 나타내는 메소드로 구성
* 생성자 : 변수에 초기값을 넣어 초기화를 시키는 것 처럼 클래스도 동일한 방식으로 생성해 초기화를 해주는 역할
* 필드 : 클래스에 포함된 변수
* 메소드 : 어떠한 특정 작업을 수행하기 위한 명령문의 집합
■ 접근제어자
- 각 접근제어를 위한 키워드에 따라 객체 또는 메서드가 접근될 수 있는 범위를 지정
* 접근제어자는 public, protected, default, private로 총 4가지이다.
접근제어자 |
클래스 내부 |
패키지 |
하위 클래스 |
그 외 |
public |
o |
o |
o |
o |
protected |
o |
o |
o |
x |
default |
o |
o |
x |
x |
private |
o |
x |
x |
x |
■ 명명규칙
- 이름의 처음은 문자나 특수문자로 시작되어야 하며, 숫자는 사용 불가능
- 자바 내부에서 정의되어 있는 키워드는 사용 불가능
- 대소문자 구분
■ 클래스 생성 예시
// 클래스 정의
public class CreateClass {
// 필드 정의
public int num;
private String name;
// 기본 생성자
public CreateClass() {
}
// 파라미터를 가진 생성자
public CreateClass(int num, String name) {
this.num = num;
this.name = name;
}
}
객체 만드는 방법 (new 키워드 이해하기)
위와 같은 방법으로 클래스를 생성한 뒤 객체를 만들어서 사용이 가능
new 키워드를 사용해서 객체를 생성하면 메모리 힙 영역에 데이터를 저장할 공간을 할당받고, 해당 영역의 주소를 객체에게 반환하여 사용가능하게 함
객체를 생성하기 위해 위에서 정의했던 클래스를 사용
■ 객체 생성 예시
// 객체 생성 예시
// 기본 생성자
CreateClass cc = new CreateClass();
// 파라미터를 가진 생성자
CreateClass cc2 = new CreateClass(1,"jaehee");
메소드 정의하는 방법
메소드는 위에서 '어떠한 특정 작업을 수행하기 위한 명령문의 집합'이라고 정의를 했었다.
바로 위에서 생성한 클래스를 이용하여 메소드를 생성해보자
■ 메소드 생성 예시
// 위의 클래스를 그대로 가져왔다
public class CreateClass {
public int num;
private String name;
public CreateClass() {
}
public CreateClass(int num, String name) {
this.num = num;
this.name = name;
}
// 메소드 정의
public String getName() {
return name;
}
}
■ 추가적으로 위에서 생성한 객체를 이용하여 메소드를 호출해보자
// 파라미터를 가진 생성자
CreateClass cc2 = new CreateClass(1,"jaehee");
// 메소드를 이용하여 이름을 가져와보자
String name = cc2.getName();
System.out.println(name);
// 결과 : jaehee
■ 메소드 오버로딩
메소드는 기본적으로 같은 이름으로 여러 개를 정의할 수 없다.
그러나, 매개변수 타입이나 수가 다르면 같은 이름으로 정의할 수 있다.
이러한 정의를 메소드 오버로딩이라고 한다.
아래는 간단한 메소드 오버로딩의 예시이다.
// 변수 a는 int 타입으로 정의되어있다고 가정
public int getCount() {
return a;
}
public int getCount(int a) {
this.a = a;
return a;
}
■ 메소드 오버라이딩
메소드는 상위 클래스가 정의한 메소드를 하위 클래스에서 재정의할 수 있다.
이번에도 간단한 메소드 오버라이딩 예시를 아래에 작성해보자
// 위의 클래스를 그대로 가져왔다
public class CreateClass {
public int num;
private String name;
public CreateClass() {
}
public CreateClass(int num, String name) {
this.num = num;
this.name = name;
}
// 메소드 정의
public String getName() {
return name;
}
}
// SecondClass는 CreateClass를 상속받는다.
public class SecondClass extends CreateClass {
// 메소드 오버라이딩 예시
@Override
public String getName() {
System.out.println("저는 SecondClass입니다.");
}
}
CreateClass cc2 = new CreateClass(1,"jaehee");
SecondClass second = new SecondClass();
String name = cc2.getName();
System.out.println(name);
// 결과 : jaehee
second.getName();
// 결과 : 저는 SecondClass입니다.
생성자 정의하는 방법
클래스 생성 방법을 할 때 이미 언급이 되었지만,
생성자는 변수를 초기화하는 것과 동일하게 클래스를 생성하고 객체를 호출할 때 객체를 초기화하기 위해 사용된다.
■ 규칙
- 생성자는 리턴 타입을 사용하지 않음
- 클래스 이름과 동일하게 사용
- 모든 클래스는 생성자를 가짐(따로 선언하지 않으면 기본 생성자가 자동으로 생성)
■ 종류
1) 기본 생성자 : 위에서 언급했지만, 생성자를 따로 선언하지 않으면 컴파일러가 자동으로 생성
2) 묵시적 생성자 : 파라미터를 가지지 않는 생성자
3) 명시적 생성자 : 파라미터를 가지는 생성자
■ 생성자 정의 예시
// 위의 클래스를 그대로 가져왔다
public class CreateClass {
public int num;
private String name;
// 묵시적 생성자
public CreateClass() {
System.out.println("묵시적 생성자 생성 완료!");
}
// 명시적 생성자
public CreateClass(int num, String name) {
this.num = num;
this.name = name;
}
}
this 키워드 이해하기
this는 객체가 자기 자신을 참조하는데 사용하는 키워드이다.
해당 객체의 참조 값인 hashcode값을 가지고 있는데, 아래의 예시를 통해 이해가 가능하다.
public class Test {
public void dump() {
System.out.println(this); // Object의 tosting()
}
}
public void thisTest() {
Test t = new Test();
t.dump();
System.out.println(t); // Object의 tosting()
}
thisTest()
// 위 결과 동일한 hashcode를 출력
■ this가 사용될 때
// 1. 객체 변수와 같은 이름을 가진 것이 존재할 때
int a;
public int getInt(int a) {
this.a = a;
return a;
}
// 2. 현재 객체를 반환할 때
public CreateClass getClass() {
return this;
}
// 3. 현재 클래스에 정의된 생성자를 부를 때
public class CreateClass {
public int num;
private String name;
public CreateClass() {
// 현재 명시적 생성자를 불러서 사용
this(1, "jaehee");
}
public CreateClass(int num, String name) {
this.num = num;
this.name = name;
}
}