오브젝트와 클래스는 객체지향 프로그래밍을 구현하기 위해 존재한다. 객체지향 프로그래밍이란 뭘까? 왜 중요할까?
객체지향 프로그래밍이란?
객체지향 프로그래밍은 프로그램을 객체들이 서로 상호작용하게 구현하는 방법이다. 원래 프로그램을 만든다고 하면, 프로그램이 뭐를 해야 하는지를 차례대로 구현해야 한다. 간단한 계산기 프로그램을 만든다면, 먼저 어떤 연산을 하는지 물어보고, 숫자를 받아오고, 계산을 해서, 결과를 보여주는 식으로 프로그램을 구현할 수 있다. 간단한 프로그램이라면 이런식으로 디자인해도 전혀 문제가 없지만, 문제는 프로그램이 복잡해지면 이러한 방식으로 하기가 쉽지 않다는 것이다.
예를 들어, 체스 프로그램을 이런 식으로 만든다고 하면, 어떻게 접근할지조차 쉽게 떠오르지 않을 것이다. 하지만, 객체지향을 사용하면 비교적 쉽게 가능하다. 어떻게 가능할까?
객체지향에서는 체스라는 프로그램이 여러가지 객체의 상호작용으로 이루어져 있다고 본다. 즉, 모든 체스 말이 하나하나의 객체이고, 체스 말의 특징을 가지고 있다. 체스 말의 특징이 무엇일까? 모든 객체는, 특성과 행동이 있다. 체스로 예를 들면, 체스 말의 특성은 이름이 뭔지, 현재 보드 위 어디에 위치에 있는지, 살아 있는지 죽었는지 등은 체스 말이 가지고 있는 특성이다. 이러한 특성을 프로퍼티(Property)라 부른다. 프로퍼티는 일반적으로 변수나 상수로 나타낸다. 다음으로, 체스 말이 가질 수 있는 행동은 움직이는 것이다. 이런 객체가 가지는 행동을 매소드(Method)라 한다.
즉, 체스 프로그램은 각각의 객체를 만들어서 그 객체의 프로퍼티와 매소드를 정의해, 이 객체가 어떻게 상호작용하는지 정의해서 만들 수 있다. 객체지향적이지 않은 방법으로 만약 체스 프로그램을 만들고자 한다면 매우 어려울 것이다.
이러한 개념이 한 번에 이해되지 않는건 당연한 것이다. 객체지향은 무엇보다 직접 구현해 보면서 이해하는게 중요하기 때문에 많은 연습이 필요하다.
객체 선언하기
그렇다면 객체를 어떻게 사용할까? 먼저, 객체를 선언하는 과정은 2가지가 있다. 객체는, 그 객체가 가진 프로퍼티와 매소드를 정의하는 과정과, 그 정의된 객체를 실제로 사용하는 과정으로 나눌 수 있다. 자동차로 예를 들면, 자동차의 설계도가 있다고 실제로 자동차가 만들어진게 아니듯, 객체도 객체를 정의했다고 실제로 객체가 만들어진 것은 아니다.
객체의 설계도는 class를 써서 정의한다. 예를 들어, 원 객체를 정의해 보자. 원 객체의 프로퍼티는 무엇일까? 프로퍼티가 뭔지 알고 싶다면 원이 가지고 있는 특성을 생각해 보면 된다. 원은 반지름을 가지고 있다. 반지름이 같은 원은 같은 원이고, 반지름이 다르면 다른 원이다. 즉, 반지름을 원을 구분짓는 특성이다. 그렇다면 원의 매소드는 뭘까? 원은 어떤 행동을 할까? 행동이라 하면 혼란스럽다. 원은 사람이 아니라 걷지도 않고 뛰지도 않는다. 하지만, 매소드는 반드시 행동일 필요는 없다. 객체가 수행할 작업 모든게 매소드가 될 수 있다. 원의 경우 지름이나 넓이 등이 매소드가 될 수 있다. 그렇다면 한 번 원 객체를 만들어 보자.
class Circle {
double radius = 1.0;
public double getArea() {
return radius * radius * 3.141592;
}
}
위의 코드에서는 원의 설계도를 정의했다. 일단, 프로퍼티에서는 반지름이라는 변수를 선언해 1.0이라는 값을 줬고, 매소드에서는 원의 넓이를 계산하도록 했다. 하지만 이상하다. 모든 원의 반지름은 1.0이 아닌데, 반지름이 1.0이라 하면, 반지름이 1.0인 원만 표현할 수 있다. 그렇기 때문에 모든 객체는 생성자(Constructor)가 있어, 객체를 생성할때 필요한 값을 지정할 수 있다. 생성자는 아래와 같이 정의한다.
class Circle {
//프로퍼티
double radius = 1.0;
//생성자
public Circle() {
}
public Circle(double newRadius) {
radius = newRadius;
}
//매소드
public double getArea() {
return radius * radius * 3.141592;
}
}
생성자는, pulic을 쓰고, 클래스와 같은 이름을 쓰면 자동으로 지정된다. 위에서도 볼 수 있듯이, 생성자는 여러개가 있을 수 있다. 여기서는, 새로운 반지름을 주지 않으면 자동으로 1.0으로 설정하고, 새로운 반지름을 준 경우에만 그 값으로 설정되게 했다.
객체 사용하기
그렇다면 선언한 객체를 사용하기 위해서는 어떻게 해야 할까? 우선, 클래스는 말했다 싶이 설계도이고, 실제로 활용하기 위해서는 객체를 만들어야 한다. 클래스로 선언한 객체를 사용하기 위해 만든 것을 인스턴스(Instance)라 한다.
인스턴스를 만들기 위해선 우선 어떤 객체를 만들지 알려줘야 한다. 여기서는 Circle이라는 객체를 만들고 싶다. 그 다음에는 인스턴스에 이름을 지어줘야 한다. 여기서는 3개의 인스턴스를 만들건데, 각각 circle1, circle2, circle3로 불러주자. 그 다음에는 새로운 객체를 만든다는 의미의 new 키워드를, 그리고 위에서 정의한대로 생성자를 써서 인스턴스를 만들 수 있다.
public class Ex {
public static void main(String[] args) {
Circle circle1 = new Circle();
Circle circle2 = new Circle(25);
Circle circle3 = new Circle(50);
}
}
위의 코드에서는 설명한 대로 인스턴스를 생성했다. 각각 1.0과 25, 50의 반지름을 가지는 원이다. 물론, 생성만 하고 아무것도 안 했으니 이 프로그램은 아무것도 하지 않는 프로그램이다. 각각 원의 반지름과 넓이를 출력하기 위해선 어떻게 해야 할까?
public class Ex {
public static void main(String[] args) {
Circle circle1 = new Circle();
Circle circle2 = new Circle(25);
Circle circle3 = new Circle(50);
System.out.println(circle1.radius);
System.out.println(circle1.getArea());
}
}
circle1의 반지름과 넓이를 출력했다. 프로퍼티에 접근하기 위해서는 인스턴스의 이름과 점(.) 뒤에 프로퍼티의 이름을 적으면 되고, 매소드에 접근하기 위해서는 인스턴스의 이름과 점(.) 뒤에 매소드의 이름과 괄호(())를 적으면 된다.
'👨💻 프로그래밍 > Java, Kotlin, Spring' 카테고리의 다른 글
자바 20 - UML 다이어그램 (1) | 2021.05.10 |
---|---|
자바 19 - static의 의미 (0) | 2021.05.08 |
자바 17 - 자바 매소드(Method), 오버로딩, Call-by-Value (0) | 2021.05.04 |
자바 16 - 2차원 배열 (2) | 2021.05.02 |
자바 15 - 배열(Arrays) (0) | 2021.04.30 |