클래스란 객체를 정의한 설계도 (또는 틀)라고 할 수 있다. 클래스는 객체를 생성하는 데 사용되며, 반대로 객체는 클래스에 정의되고 설계된 내용 그대로 생성된다.
정리하면, 클래스는 객체 그 자체가 아니라 단지 객체를 생성하는데 사용되는 하나의 틀이다.
(클래스를 통해 생성된 객체를 해당 클래스의 인스턴스라고 부른다.)
클래스는 다음과 같이 정의하며 클래스 명은 주로 대문자로 시작한다.
class 클래스명 { // 클래스 정의
...
}
클래스는 4가지 요소로 구성되어있다.
public class ExampleClass {
int x = 10; // (1)필드
void printX() {...} // (2)메서드
ExampleClass {...} // (3)생성자
class ExampleClass2 {...} // (4)이너 클래스
}
1) 필드 : 클래스의 속성을 나타내는 변수이다.
2) 메서드 : 클래스의 기능을 나타내는 함수이다.
3) 생성자 : 클래스의 객체를 생성하는 역할을 한다.
4) 이너 클래스 : 클래스 내부의 클래스를 의미한다.
필드, 메서드, 이너 클래스 3개 요소를 클래스의 멤버라고 부른다.
객체는 크게 속성과 기능 두가지 요소로 이루어져있다.
속성과 기능은 각각 필드와 메서드로 정의되며, 일반적으로 하나의 객체는 다양한 속성과 기능의 집합으로 이루어져있다.
new 키워드를 사용해서 실제 객체를 생성할 수 있다.
클래스명 참조_변수명; // 인스턴스를 참조하기 위한 참조변수 선언
참조_변수명 = new 생성자(); // 인스턴스 생성 후, 객체의 주소를 참조 변수에 저장
//줄여서 다음과 같이 가능하다.
클래스명 참조_변수명 = new 생성자();
new 키워드와 생성자를 통해서 클래스의 객체를 생성하는 것은 해당 객체를 힙 메모리에 넣고 그 주소값을 참조변수에 저장하는 것과 같다.
(.)를 통해 해당 객체의 멤버에 접근이 가능하다.
참조 변수명.필드명 // 필드값 불러오기
참조 변수명.메서드명() // 메서드 호출
필드는 '클래스에 포함된 변수'를 의미하는 것으로 객체의 속성을 정의할 때 사용된다.
자바에서 변수는 크게 1) 클래스 변수 2) 인스턴스 변수 3)지역변수 가 있다.
이중 필드라고 부르는 것은 1) 클래스 변수 와 2) 인스턴스 변수이다.
이 둘은 다시 static 키워드의 유무 로 구분할 수 있다.
static 키워드가 함께 선언된 것은 1) 클래스 변수,
그렇지 않은 것은 2) 인스턴스 변수이다.
이 두가지 유형에 포함되지 않고 메서드 내에 포함된 모든 변수를 3) 지역변수라고 부른다.
//예시
class Example { // => 클래스 영역
int instanceVariable; // 인스턴스 변수
static int classVariable; // 클래스 변수(static 변수, 공유변수)
void method() { // => 메서드 영역
int localVariable = 0; // 지역 변수. {}블록 안에서만 유효
}
}
1) 클래스 변수
클래스 변수는 공통된 저장공간을 공유한다.
따라서 한 클래스로부터 생성되는 모든 인스턴스가 특정한 값을 공유해야하는 경우에 static 키워드를 사용해서 클래스 변수를 선언한다.
또한, 클래스 변수는 인스턴스를 따로 생성하지 않고도 클래스.클래스변수명 을 통해 사용 가능하다.
2) 인스턴스 변수
인스턴스가 가지는 각각의 고유한 속성을 저장하기 위한 변수로 new 생성자() 를 통해 인스턴스가 생성될 때 만들어진다.
클래스를 통해 만들어진 인스턴스는 힙 메모리의 독립적인 공간에 저장되고, 동일한 클래스로부터 생성되었지만 객체의 고유한 개별성을 가진다.
static은 클래스의 멤버 (필드, 메서드, 이너클래스)에 사용하는 키워드이다.
static 키워드가 붙어있는 멤버를 '정적 멤버 (static member)'라고 하고, 붙어있지 않은 인스턴스 변수와 구분한다.
가장 중요한 것은
1) static member는 객체 간 공유 변수의 성질이 있다.
(일반적인 메서드 앞에 static 키워드를 사용하면 정적메서드가 된다.)
2) 정적 메서드의 경우 인스턴스 변수 또는 인스턴스 메서드를 사용할 수 없다.
정적 메서드는 인스턴스 생성없이 호출 가능하기 때문에 얘가 호출되었을 때 인스턴스가 존재하지 않을 수 있기 때문이다.
public class StaticFieldTest {
public static void main(String[] args) {
StaticField staticField1 = new StaticField(); // 객체 생성
StaticField staticField2 = new StaticField();
staticField1.num1 = 100;
staticField2.num1 = 1000;
System.out.println(staticField1.num1);
System.out.println(staticField2.num1);
staticField1.num2 = 150;
staticField2.num2 = 1500;
System.out.println(staticField1.num2);
System.out.println(staticField2.num2);
}
}
class StaticField {
int num1 = 10;
static int num2 = 15;
}
//출력값
100
1000
1500
1500
메서드는 '특정 작업을 수행하는 일련의 명령문들의 집합을 의미하며, 클래스의 기능에 해당하는 내용들을 담당한다.
메서드는 크게 머리에 해당하는 메서드 시그니처와 몸통에 해당하는 메서드 바디로 구분한다.
자바제어자 반환타입 메서드명(매개 변수) { // 메서드 시그니처
메서드 내용 // 메서드 바디
}
메서드 시그니처는 순서대로 '해당 메서드가 어떤 타입을 반환하는가 (반환타입), 메서드 이름이 무엇 (메서드 명)이며, 해당 작업을 수행하기 위해 어떤 재료들이 필요한지 (매개변수)' 에 대한 정보를 가지고 있다.
메서드의 반환타입이 void가 아닌 경우 메서드 바디 안에 반드시 return 문이 있어야한다.
여기서 결과값은 반드시 반환타입과 일치하거나 자동 형변환이 가능한 것이어야한다.
메서드이름(매개변수1, 매개변수2, ...); // 메서드 호출방법. 매개 변수가 없을 수도 있음.
printHello();
getNumSeven();
multiply(4, 4.0);
메서드 호출 시 괄호안에 넣어주는 입력 값 '인자(argument)’라고 하는데 인자의 개수와 순서는 반드시 메서드를 정의할 때 선언된 매개변수와 일치되어야 한다.
오버 로딩이 되기 위해서는 아래 두가지 조건이 성립되어야 한다.
1) 메서드의 이름이 같아야한다.
2) 매개변수의 개수 또는 타입이 달라야한다.
(이 조건이 하나라도 충족되지 않으면 중복 정의로 간주되어 컴파일 에러가 생긴다.)
오버로딩의 예시로는 println() 메서드를 생각하자.