나는 “객체지향 프로그래밍이 무엇이냐”고 물어본다면 “객체 간의 협력으로 이루어진 프로그래밍이다” 라고 설명할 것이고, “왜 객체지향 프로그래밍을 해야 하냐?”고 물어본다면 “코드의 재사용성과 유지보수성이 높으니까”, “자바는 객체지향 언어어니까!” 와 같이 교과서적인 답변같은 말을 할 것 같다.
왜냐하면 나도 왜 객체지향이 쓰이는지 잘 모른다,,! 저렇게 배웠으니 저렇게 알고있을 뿐,, 이번 기회에 객체지향에 대해 잘 설명할 수 있도록 학습해보고자 한다.
객체지향 프로그래밍; OOP
프로그램은 절차에 따라 실행된다.
절차에 따라 코드를 작성하게 되면 프로그램의 볼륨이 너무 커지게 된다. 이를 함수로 나누어 구조적인 프로그래밍으로 변경할 수 있을 것이다.
하지만 구조적인 프로그래밍에서도 어떠한 문제가 있었으며, 새로운 방식이 필요했을 것이다. 그렇게 탄생한 것이 객체지향 프로그래밍이다.
과연 어떤 문제가 발생했으며 어떤 방식으로 해결했을까?
캡슐화 (Encapsulation)
캡슐화란 데이터 구조와 함수를 하나의 영역에 함께 모아 놓는 작업이라고 할 수 있다.
만약 학생의 성적을 등록하고 관리하는 절차적인 프로그램을 잘라서 프로그램을 구조적으로 만들어보자. 한 파일에 여러 기능을 가진 함수가 생성될 것이다. addStudent(Student student)
, editStudent(Student student)
, …
무분별하게 정렬되어 있는 많은 함수들은 분리하여 저장해야 할 것이다. 그럼 어떻게 분리하여 저장할 것인가. 기능을 중심으로?(inputXxx, printXxx, .. ) 데이터를 중심으로?(xxxStudent, xxxExams, … )
정답은 “데이터를 기준으로 묶어야 한다”
이다.
왜? 함수 모듈의 독립성을 지키기 위함이다. 함수는 외부 코드의 변경에 절대 영향을 받으면 안된다. 그렇기 때문에 우리는 함수에 매개변수를 전달한다. 하지만 매개변수로 아래의 구조화된 데이터를 전달한다고 가정한 경우에는 어떨까
Ellipse
타입 데이터를 매개변수로 받는 draw
함수가 있다고 가정해보자.
class Ellipse {
int x, y, w, h;
int color;
}
Ellipse
의 x
라는 변수이름을 a
라고 변경했다고 가정해보자. 그럼 draw()
함수는 오류가 발생할 것이다.
void draw(Ellipse ellipse) {
System.out.println( ellipse.x + ellipse.y ... )
}
위에서 언급했듯이 함수는 외부 코드의 변경에 절대 영향을 받으면 안된다. 하지만 영향을 받아버렸다..!
그렇다면 이 문제를 해결하기 위해서는 어떻게 해야할까 Ellipse
의 변수명을 절대로 변경하지 말아야 할까? Ellipse
의 변수명을 변경했을 때, 영향을 미치는 모든 코드를 수정해야할까?
방법은 Ellipse
의 데이터를 변경했을 때 오류가 나는 함수들을 Ellipse
를 구현한 파일에 모두 모아 놓는 것이다.
이것을 캡슐화 (encapsulation)
라고 한며, 이 클래스를 객체
라고 부른다.
이렇게 하면 데이터 구조에 따른 코드의 수정 범위를 캡슐 범위로 한정할 수 있다.
public class Ellipse {
int x, y, w, h; // 값이 저장되어 있다고 가정한다.
int color;
public void draw(){
System.out.println( x + y ... )
}
}
이러한 구조가 되었을 때, 우리는 draw 메소드는 인스턴스
에 의해 실행될 수 있다.
// Ellpse 인스턴스를 생성하고 주소를 ellipse에 저장
Ellipse ellipse = new Ellpse();
// ellipse의 draw 메소드 실행
ellipse.draw();
객체지향이 탄생한 이유와 캡슐화가 필요한 이유에 대해 알아보았다. 캡슐화를 사용하여 데이터의 변경으로 인한 오류 발생 범위를 좁힐 수 있고, 이는 자연스럽게 유지보수에 용이한 코드로 변화하게 된다.
딱딱한 정리 내용은 아래 게시글을 참고하자
'JAVA' 카테고리의 다른 글
[JAVA] 컴파일과 런타임을 간단하게 알아보자 (0) | 2023.03.25 |
---|---|
[JAVA] 코드의 배포와 재사용 (0) | 2023.03.24 |
[JAVA] Runtime Constant Pool? 자바는 상수와 문자열을 어떻게 변수에 저장할까 (0) | 2023.03.24 |
[JAVA] 상속 (Inheritance) - Is A (0) | 2023.03.23 |
[JAVA] 얕은 복사와 깊은 복사 (0) | 2023.03.23 |