아래의 예제는 의미적으로 연관된 로직들을 물리적으로 응집된 하나의 객체로 만드는 법을 설명하는 예제다.
본 수업에서는 아래의 코드를 기본 예제로 사용할 것이다. 우리 수업의 목적은 개론서이기 때문에 다양한 코드 경험보다는 개념의 빠른 이해를 목적으로 하고 있다. 처음 시작하는 입장에서는 개념도 쉽지 않는데 새로운 개념이 등장할 때마다 새로운 코드가 등장한다면 부담이 두배가 될 것이다. 필자는 개념의 이해는 쉽게 하는 것이 바람직하다고 생각한다. 그래서 본 수업은 계산기의 예제를 크게 벗어나지 않을 것이다. 빠른 속도로 수업 전체를 완주 한 후에 예제가 풍부한 다른 개론서를 천천히 완주하는 방법을 추천한다. 마음 같아서는 적당한 규모의 실제 프로젝트를 한줄 한줄 해석하면서 따라해보는 수업도 만들어보고 싶다. 할 수 있을까? ^^
위의 예에서 변수 left와 right, 메소드 sum과 avg는 연관되어 있는 로직이다. 이 로직들의 연관성은 계산을 하기 위한 것이다. 그래서 필자는 이 로직들을 대표하는 이름을 계산기라는 의미의 Calculator라고 정하고 이것들을 Calculator이라는 이름으로 그룹핑하고 싶다. 이럴 때 사용하는 키워드가 class이다. class 키워드 뒤에는 클래스 이름이 오고 그 뒤의 중괄호는 클래스의 시작과 끝의 경계를 의미한다. 이렇게 해서 더하기(sum)와 평균(avg)를 계산 할 수 있는 클래스가 만들어졌다. 클래스는 아래와 같이 정의 할 수 있다.
클래스는 연관되어 있는 변수와 메소드의 집합이다.
인스턴스
이제 클래스를 사용하는 방법을 알아보자. 클래스는 일종의 설계도다. 클래스를 정의하는 것 자체로는 할 수 있는 일이 많지 않다. 설계도를 구체적인 제품으로 만들어야 한다. 그 때 사용하는 키워드가 new이다. 25번 라인을 보자.
Calculatorc1=newCalculator();
new Calculator()은 클래스 Calculator를 구체적인 제품으로 만드는 명령이다. 이렇게 만들어진 구체적인 제품을 인스턴스(instance)라고 부른다. 아래의 관계를 기억하자.
클래스 : 설계도
인스턴스 : 제품
위의 코드는 new를 이용해서 만든 인스턴스를 변수 c1에 담고 있다. 변수 c1에 인스턴스를 담은 이유는 c1을 통해서 인스턴스를 제어해야 하기 때문이다. 그런데 c1 앞에 Caculator가 위치하고 있다. 지금까지 우리는 여러가지 변수를 선언해왔다. 예를들어서 변수 a는 변수가 담을 수 있는 데이터 타입에 따라서 아래와 같이 다양한 형태로 선언된다.
그럼 아래와 같은 구문은 변수명 c1의 데이터 타입이 무엇이라는 의미일까?
Calculatorc1
Calculator라는 의미다. 즉 클래스를 만든다는 것은 사용자 정의 데이터 타입을 만드는 것과 같은 의미다. 하지만 지금 단계에서는 사용자 정의 타입이라는 개념이 쉽게 와닿지 않을 것이기 때문에 이에 대한 설명은 차차로 하겠다. 지금 기억할 것은 클래스를 인스턴스화 할 때는 변수에 담아야 한다는 것과 이 때 사용하는 변수의 데이터 타입은 그 클래스가 된다는 점이다.
클래스와 인스턴스는 설계도와 제품이라고 설명했다. 그럼 객체는 클래스일까 인스턴스일까? 다소 논란이 있지만 일반적으로 설계도인 클래스가 구체적인 실체인 인스턴스가 되었을 때 객체라고 부른다. 보통은 구체적인 코드 상에서 나타는 객체를 인스턴스라고 부르고, 로직을 설계 할 때 나타나는 인스턴스를 객체라고 부른다. 또는 클래스, 인스턴스의 구분없이 포괄적으로 객체라는 말을 쓰기도 한다. 이런 혼란을 피하기 위해서 필자는 가급적 클래스와 인스턴스를 사용하도록 하겠다. 이에 대한 논의는 생활코딩 페이스북 그룹을 참고하자.
클래스를 단순히 변수와 메소드의 묶음으로 보면 부족하다. 우리가 객체를 만들어서 사용하는 이유는 재활용성을 높이기 위해서다.
위의 코드를 보면 두개의 인스턴스를 각각 c1과 c2에 담았다. 그리고 각각의 인스턴스에 소속된 메소드를 호출하고 있다. 각각의 인스턴스는 메소드 setOprands를 통해서 변수 left, right의 값을 설정하고 있다. 그 결과 인스턴스 C1과 C2는 아래와 같이 서로 다른 변수의 값을 내부적으로 가지고 있게 된다.
이 때 메소드 setOprands 내에 this.이라는 것이 있다. this는 클래스를 통해서 만들어진 인스턴스 자신을 가리킨다. 위의 코드에서 left는 매개변수이고 이 변수는 setOprands 밖에서는 접근 할 수 없다. 반면에 this.left는 4행에서 선언한 변수에 값을 설정하는 것이고 메소드 밖에서 선언한 변수는 인스턴스 내의 모든 메소드에서 접근이 가능하다. 이에 대한 이야기는 뒤에서 차차 하겠다. 이해가 안가더라도 걱정하지 말자.