객체지향이 무엇인가?
객체지향은 데이터를 객체로 만들어 구조화된 프로그래밍 기술입니다.
그렇다면 왜 객체를 굳이 사용해서 프로그래밍 해야할까요?
절차지향으로 구현
예를 들어 학생 정보를 관리하는 프로그램을 만든다고 생각해봅시다.
그러면 C 언어를 사용해 구현한다면 다음과 같을것입니다.
#include <stdio.h>
// 구조체 정의
struct Student {
char name[50];
int age;
float score;
};
// 함수 정의
void displayStudent(struct Student s) {
printf("Name: %s\n", s.name);
printf("Age: %d\n", s.age);
printf("Score: %.2f\n", s.score);
}
int main() {
// 학생 정보 초기화
struct Student student;
strcpy(student.name, "John");
student.age = 20;
student.score = 3.5;
// 학생 정보 출력
displayStudent(student);
return 0;
}
/*
출력
Name: John
Age: 20
Score: 3.5
*/
학생을 구조체로 정의하고
학생의 정보를 출력하는 함수를 만들어 사용하면 됩니다.
그런데 학생 정보 뿐만 아니라 교사의 정보도 관리하게된다면 어떻게될까요?
그러면 다음과 같이 교사의 구조체도 추가되고 출력 함수도 추가될것입니다.
#include <stdio.h>
#include <string.h>
// 학생 구조체 정의
struct Student {
char name[50];
int age;
float score;
};
// 교사 구조체 정의
struct Teacher {
char name[50];
int age;
char subject[50];
};
// 학생 정보 출력 함수
void displayStudent(struct Student s) {
printf("Student\n");
printf("Name: %s\n", s.name);
printf("Age: %d\n", s.age);
printf("Score: %.2f\n", s.score);
printf("\n");
}
// 교사 정보 출력 함수
void displayTeacher(struct Teacher t) {
printf("Teacher\n");
printf("Name: %s\n", t.name);
printf("Age: %d\n", t.age);
printf("Subject: %s\n", t.subject);
printf("\n");
}
int main() {
// 학생 정보 초기화
struct Student student;
strcpy(student.name, "John");
student.age = 20;
student.score = 3.5;
// 학생 정보 출력
displayStudent(student);
// 교사 정보 초기화
struct Teacher teacher;
strcpy(teacher.name, "Mr. Smith");
teacher.age = 35;
strcpy(teacher.subject, "Math");
// 교사 정보 출력
displayTeacher(teacher);
return 0;
}
/*
출력
Name: John
Age: 20
Score: 3.5
Name: Mr. Smith
Age: 35
Subject: Math
*/
코드가 좀 길어졌습니다.
그렇다면 여기서 그치지않고 다른 교직원의 정보도 같이 관리해야한다면 어떨까요?
다시 구조체와 구조체에 대한 함수가 나올것입니다.
그럼 이제 문제점들이 발생하기 시작합니다.
- 구조체 전용으로 쓰이는 함수들(display)이 모두 같은 공간에 정의된다.
구조체 전용 함수들을 모두 사용자가 알맞게 사용해야한다. 구조체마다 전용 함수들을 관리하기 힘들다.
(예를들어 Student에서 쓰이는 함수 10개 Teacher에서 쓰이는 함수 10개가 섞여있다고 생각해보자. 구분이 난감해진다.)
- 구조체별로 중복되는 코드들이 생긴다. (Student와 Teacher에서 공통으로 쓰이는 변수가 존재한다.)
왜 이런 문제가 발생하는걸까요?
서로 다른 구조체들끼리 관계를 형성할 수 없기 때문입니다.
구조체들끼리 관계를 형성하고 구조체 내의 함수를 사용한다면 문제점들이 해결될것입니다.
이것이 객체입니다.
데이터들의 맴버 변수와 메서드를 가지면 그것이 객체가 되고,
이러한 객체들끼리 서로 상호작용이 가능해집니다.
객체지향으로 구현
그럼 위의 코드를 객체로 구현해보면 어떻게 될까요?
public class Main {
// 사람 클래스 정의
static abstract class Person {
private String name;
private int age;
// 생성자
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 추상 메서드
public abstract void display();
// 사람 정보 출력 메서드
void displayPerson() {
System.out.println("Name: " + name);
System.out.println("Age: " + age);
}
}
// 학생 클래스 정의
static class Student extends Person {
float score;
// 생성자
public Student(String name, int age, float score) {
super(name, age);
this.score = score;
}
// 재정의된 display 메서드
@Override
public void display() {
displayPerson();
System.out.println("Score: " + (int)score);
System.out.println();
}
}
// 교사 클래스 정의
static class Teacher extends Person {
private String subject;
// 생성자
public Teacher(String name, int age, String subject) {
super(name, age);
this.subject = subject;
}
// 재정의된 display 메서드
@Override
public void display() {
displayPerson();
System.out.println("Subject: " + subject);
System.out.println();
}
}
public static void main(String[] args) {
// 학생 객체 생성
Person student = new Student("John", 20, 3.5f);
// 학생 정보 출력
student.display();
// 교사 객체 생성
Person teacher = new Teacher("Mr. Smith", 35, "Math");
// 교사 정보 출력
teacher.display();
}
}
/*
출력
Name: John
Age: 20
Score: 3
Name: Mr. Smith
Age: 35
Subject: Math
*/
한눈에 봐도 C 로 구현했을때보다 main 함수가 굉장히 깔끔해졌습니다.
또한 이번엔 둘다 동일한 추상화된 Person 클래스로부터 상속을 받아
Student 와 Teacher 사이에 관계가 생성되었습니다.
이로인해 동일한 display 함수를 재정의하여 사용할 수 있게되었습니다.
객체들의 맴버 변수들은 private으로 설정했습니다.
그래서 John의 score 의 구체적인 값은 3.5 지만
외부에 노출되는 display 함수에는 소수점을 없앤 3만 나타나게됩니다.
그래서 중요한 데이터는 숨기고 외부에 노출하고 싶은 데이터만 안전하게 표시할 수 있게되었습니다.
(C로 구현한 예제에서는 student.score로 언제든지 데이터에 접근이 가능합니다.)
이것이 객체지향의 특징인 추상화, 상속, 다형성(재정의), 캡슐화(노출 관리) 입니다.
결론
'Java' 카테고리의 다른 글
추상클래스, 인터페이스의 문법적,의미적 차이 (0) | 2024.05.22 |
---|---|
[객체지향설계원칙] SRP (0) | 2024.05.14 |
GC는 어떻게 이루어지는가? (0) | 2024.01.29 |
객체 지향이란? (0) | 2024.01.17 |
Java의 특징과 동작원리 (0) | 2024.01.17 |