Java Classes (1)
Declaring classes
Java에서 class를 선언하는 문법은 다음과 같다.
class MyClass {
// fields, constructor, methods
// ...
// ...
}
class MyClass extends MySuperClass implements MyInterface, YourInterface {
// fields, constructor, methods
// ...
// ...
}
Components in Class Declarations
- Modifiers (public, private, protected 등)
- Class name (일반적으로 대문자로 시작)
- Parent class (extends 키워드 뒤에)
- Interfaces (implements 키워드 뒤에, 여러 개인 경우 쉼표로 구분)
- Class body (중괄호 내부)
Modifier는 다음과 같이 class 내부 field에 누가 접근할 수 있는지에 대한 범위를 설정한다.
Access Modifiers
- public: 모두가 접근 가능
- protected: subclass에서 접근 가능
- modifier 없음: 같은 패키지 내부에서 접근 가능
- private: 본 class 내부에서만 접근 가능
field 선언은 modifier, data type과 이름 순서대로 적으며, method 선언은 modifier, return type, method 이름을 적고 괄호 내부에 parameter를 적은 다음, 중괄호 내부에 method body를 적는다. 예시는 다음과 같다.
public int speed;
private int score;
public double calculateAnswer(double n1, double n2, int a){
// calculations
// double 타입의 값을 return
}
method의 이름과 parameter type을 통해 method를 고유하게 구분할 수 있다. 이를 method signature라 한다.
또한, class가 호출되었을 때 새로운 object를 만들어내야 하는 작업을 하는 특수한 method를 Constructor라 한다. 일반적인 method와 다르게 constructor의 선언에는 return type이 없으며, constructor의 이름은 class의 이름과 동일해야 한다. Constructor는 object를 초기화할 때 new 연산자를 통해 호출된다.
Parameters and Method Overloading
Method 혹은 Constructor의 정의에서 적는 variable의 목록을 parameters라 한다. 또한 이 method 혹은 constructor를 외부에서 호출할 때, 이들에게 실제로 전달되는 값들을 arguments라 한다.
한 class에서, 이름은 같지만 parameter type이 다른 두 method가 있으면 method signature가 다르기 때문에 이를 구별할 수 있다. 이렇게 이름이 같은 여러 개의 method를 만드는 것을 method overloading이라 한다.
public class DataArtist {
public void draw(String s) {
// ...
}
public void draw(int i) {
// ...
}
public void draw(int i, double f) {
// ...
}
}
또한, method는 가변적인 개수의 parameter를 가질 수 있는데, varargs라는 구문을 이용한다. varargs는 다음 예시와 같이 점 3개(...)를 통해 사용하며, 이렇게 들어온 parameter는 array처럼 호출해 사용할 수 있다.
public Polygon polygonFrom(Point... corners) {
int numberOfSides = corners.length;
double squareOfSide1, lengthOfSide1;
squareOfSide1 = (corners[1].x - corners[0].x)
* (corners[1].x - corners[0].x)
+ (corners[1].y - corners[0].y)
* (corners[1].y - corners[0].y);
lengthOfSide1 = Math.sqrt(squareOfSide1);
// ...
}
Parameter는 primitive data type을 가질 수도, reference data type(즉, 어떤 class의 object)일 수도 있다. Reference type을 parameter로 넘겨줄 경우, method의 실행이 끝나고 return한 후까지, 그 reference type은 계속 한 object를 가리킨다. 따라서, method에 object를 넘겨줌으로써 그 method가 object의 field 등을 직접 수정할 수 있다. (object를 복사해서 넘겨주는 것이 아님)
Creating an Object
Java에서 object를 생성하는 것은 다음 세 가지 단계로 나뉜다.
Three statements in Object Creation
- Declaration: 새로운 variable의 이름을 해당하는 object type과 연결하는 것
- Instantiation: new 키워드를 이용해 해당 class의 새로운 object에 대한 메모리를 할당받는 것
- Initialization: constructor를 호출해 새로 만들어진 object의 field 등을 초기화하는 것
예를 들어, 아래 코드 한 줄은 이 세 가지 작업을 모두 수행한다.
Point originOne = new Point(23,94)
// Point originOne -> Declaration
// new -> Instantiation
// Point (23,94) -> Initialization (calling the constructor)
Garbage Collector
Java와 같은 OOP 언어는 불필요한 object를 메모리에서 제거하기 위한 Garbage Collector를 가지고 있다.
Java runtime 환경에서, 어떤 object를 참조하는 변수가 더 이상 없거나, object를 참조하던 local variable에 접근할 수 없게 된 경우, garbage collector가 해당 object는 더 이상 쓰이지 않는다고 판단하여 메모리에서 제거한다. 이를 통해 우리는 C/C++에서와 다르게 메모리 free에 대한 걱정 없이 object를 생성하고 이용할 수 있다.
Returning a Class or Interface
Java에서는 method의 return type에 class나 interface의 이름을 넣을 수 있다. 그렇게 만들어진 method의 return 값은 해당 class 혹은 interface를 implement하는 class, 혹은 그 subclass의 object여야 한다.
public Bicycle seeWhosFaster(Bicycle myBike, Bicycle yourBike) {
Bicycle fastest;
// ...
return fastest;
}
Static Fields and Class Methods
Static field와 class method는 class의 특정 instance가 아니라, 해당 class 자체에 종속된 field 및 method이다. 이들은 static modifier를 이용해 선언한다. 또한 호출할 때도 instance를 만들 필요 없이. class 이름 바로 뒤에 .을 붙여 접근할 수 있다.
public class Bicycle {
private static int numberOfBicycles = 0;
public static int getNumberOfBicycles() {
return numberOfBicycles;
}
}
int number = Bicycle.getNumberOfBicycles();
또한, static 뒤에 final modifier가 붙은 field는 일반적으로 수학 상수 등 상수를 정의하는 데 사용한다.
다음 포스트에서는 더 심화된 class 문법을 간단히 정리해볼 예정이다.