자바의 클래스도 C++에서와 마찬가지로 객체를 생성하기 위해 사용된다. 클래스로부터 만들어진 객체를 흔히 인스턴스라 한다. 객체와 인스턴스의 차이를 굳이 둘 필요는 없으나, 엄밀히 말하면 다른 것이다.
객체는 포괄적인 의미를 내포하고 있으므로 우리가 보고 느끼고 인지할 수 있는 모든 것을 의미하고, 인스턴스는 객체가 어떤 클래스로부터 생성되었다는 의미를 부각한 것이다. 하지만 혼용해서 사용하는 경우도 많기 때문에 참고만 하자.
클래스는 class 키워드로 정의할 수 있으며 클래스의 이름은 대문자로 시작하는 것이 관례이다. 클래스는 필드, 메서드, 생성자, 이너 클래스로 구성된다.
사실 위 내용은 C++의 내용과 비슷하므로, 자세한 설명은 하지 않겠다. 다만, 한가지 차이점에 대해서만 간단히 다루겠다. 기존 C++과는 다르게 자바에는 소멸자가 없다.
그 이유는 Java는 수동 메모리 해제를 지원하지 않기 때문이다. 실제로 동적할당 메모리에 대해서도 delete를 하지 않아도 된다. 이는 Java 언어의 기능 중 하나인 garbage collector 기술로 개체 소멸을 처리하기 때문이다. JVM이 객체가 더 이상 사용되지 않는다고 판단하면 자동으로 힙 메모리에서 개체를 제거하므로 메모리 누수를 방지하는 데 도움이 된다.
객체의 생성은 new 키워드를 통해 할 수 있다. 또한 생성된 객체에 닷 연산자(.)를 이용하여 멤버에 접근할 수도 있다. 이 때부터 객체는 인스턴스화 되었다고 하며, 하나의 클래스에 대해 여러 인스턴스가 생성될 수 있다. 객체 생성 형식은 아래와 같다.
닷 오퍼레이터를 이용하면 객체의 멤버함수나 멤버변수에 접근할 수 있다.
정보 은닉이란 객체지향 프로그래밍에서 접근 가능한 최소한의 정보만 오픈함으로써, 객체의 오류를 방지하고 클라이언트가 객체를 더 효율적으로 활용할 수 있게 하는 기법이다. 바로 이러한 정보 은닉을 위해 캡슐화와 접근 제어자를 사용한다.
먼저 캡슐화란, 관련있는 멤버 변수와 메서드를 하나의 클래스로 묶어 외부에서 쉽게 접근하지 못하도록 만드는 기법이다.
다음으로, 접근제어자(Access Modifier)는 클래스 외부에서 클래스의 멤버 변수, 메서드, 생성자에 접근할 수 있는지 여부를 결정하는 키워드이다. 종류는 아래와 같다.
하지만, 가끔은 private으로 선언된 멤버 변수에 대해 접근 또는 수정이 필요할 수 있다. 이럴 때에는 public으로 제공되는 getter, setter를 이용할 수 있다.
메서드는 선언부와 구현부로 구성된다. 선언부에는 반환타입, 메서드 명, 변수 타입, 변수명으로 구성된다. 구현부는 반환 값이 있는 경우와 없는 경우로 나눌 수 있다. 만약 반환 값이 없다면 함수의 반환타입은 void가 되어야 하고, 반환 값이 있다면 함수의 반환타입과 동일해야 한다.
메서드를 호출하는 방법과 매개변수는 기본적으로 C++에서의 방식과 동일하다. 또한 매개변수(parameter)를 다르게 줌으로써, 같은 이름의 함수를 다르게 정의할 수도 있다. 이를 메서드 오버로딩이라고 한다.
위에서 말한 바 있듯, 오버로딩은 이름은 같지만 매개변수의 개수나 타입이 달라 구별되는 경우를 의미한다. 근데 만약 인자를 하나 받는 경우, 둘 받는 경우, … , 백 개를 받는 경우를 모두 구현해야 하는 상황이 생긴다면 어떻게 해야 할까? 이를 하나하나 오버로딩하는 일은 비효율적일 것이다. 이 때 사용할 수 있는 것이 가변인자(Variable Arguments)이다. 가변인자를 사용하는 방법은 키워드 …을 이용하는 것이다. 형태는 아래와 같다.
위의 sum함수는 문자열 몇 개를 입력 받든 모두 이어 붙인 결과를 출력한다. 이를 사용하는 방법은 다음과 같다.
만약, 가변인자 외의 다른 매개변수가 있다면, 가변인자는 마지막에 선언해야 한다.
위 코드의 실행결과는 a-b-c-가 된다. 가변인자를 사용하는 메서드를 오버로딩 할 경우, 컴파일러가 어떤 메서드를 사용해야 할지 구분할 수 없어 에러가 발생한다. 따라서 가변인자 메서드는 오버로딩하지 않아야 할 것이다.
try-catch문은 프로그램의 오류에 대해 예외처리를 해주기 위해 사용한다.
즉, try는 원래 작성하려던 코드 중 에러 발생이 의심되는 코드를 넣으면 되고, catch에는 try문에서 에러가 발생할 경우 실행될 코드를 넣어주면 된다. 특히, catch의 파라미터에는 예외클래스가 들어가는데, 이 예외 클래스는 아래에서 자세히 다루기로 하자. try-catch문의 실행 예시는 다음과 같다.
참고로 throw new Exception()을 사용하면 강제로 Exception을 발생시킬 수 있다.
try-catch문에 뒤이어 finally를 쓰기도 하는데, try-catch-finally 로 사용하기도 하고, try-finally형태로 사용하기도 한다. finally안의 실행문은 try블록 안에서 일어난 일과 관계없이 finally안의 구문을 실행한다.
try-finally와 try-catch-finally의 실제 사용예제를 보자.