본문 바로가기
카테고리 없음

객체 지향 프로그래밍 (OOP)

by 연제원 2021. 1. 14.

객체 지향 프로그래밍(Object-Oriented Programming)에 대해서 공부하기 전에 알아야 할 개념들이 있다.

(객체지향은 이데아론에서 시작되었다고 한다..?!)

바로 클래스(Class)객체(Object)다. 지금의 나로써는 명확한 정의를 내리기 어려우니 예시를 들어 정리해보려고 한다.

 

 

허접하지만 일단 '사과'들이다.

한 번 단순히 사과라는 것을 생각해보자. 머리속에서 정확한 색(RGB), 크기, 무게 등을 생각하지 않고 대충 사과는 어떤지만 생각한다!

그런데 우리(인간)은 위 사진을 봤을 때, 전부 사과라고 인식한다. 크기(큰지, 작은지), 색깔(진한지, 연한지), 잎의 유무 등을 신경쓰지 않고 보자마자 이건 사과다! 라고 인식할 수 있다. 왜냐하면 우리의 머리 속에는 이미 정확하진 않지만 어떠한 이상적인 사과라는 원본이 있기 때문에, 실제(현실에 있는) 사과를 보면 추상화를 통해 사과라고 생각할 수 있는 것이다.

이때, 우리 머리 속에 있는 사과에 대한 어떠한 이상적인 원본클래스라고하고, 위 사진에서 크기, 색 등이 각기 다르지만 전부 (현실에 있는)사과라고 할 수 있는 이것들객체라고 할 수 있다.

 

다시 사과에 비유를 하며 정리를 해보자

클래스 (Class)

가장 추상적이고 내부에 구체적인 무언가가 없는 원형

가장 중요한 특성만 개략적으로 알려줌

실제로 존재 ❌

구체적인 수치 ❌

 

(추상화를 통해 인식)

객체 (Object)

하나의 온전한 단위로 존재(각각 사과라고 인지)

각각 서로에게 영향을 미치지 않는다.(사과 1개가 사라져도 영향 )

실제로 존재 ⭕

구체적인 수치 ⭕

 

 

(우리 머리속에 이상적인)사과가 클래스라면 (실제로 존재하는)각각의 사과는 객체다. 사과(객체)마다 색, 크기, 무게는 다 다르지만 어쨌든 색, 크기, 무게라는 속성을 가진다.

즉 사과라는 클래스는 색, 크기, 무게 등의 속성이 존재하고, 객체들은 색, 크기, 무게 등의 값이 다르기 때문에 각각 다른 객체로 분류가 된다

거꾸로 생각해보자면 사과가 공통적으로 갖는 속성들을 모아서 정의내린 것을 클래스라고도 한다.

 

결론을 내려보자

 

클래스(Class)

객체를 정의해놓은 것
각 속성(색, 크기, 무게 등)이 존재하지만 구체적이지 않다!
사람의 경우 머리속에 있는 사과라는 정의

객체(Object)

클래스를 기반으로 현존하는 무언가
실제로 존재하는 것 (현존하는 사과)
각 속성(색, 크기, 무게 등)이 매우 구체적이다!

엄밀히 말하자면 인스턴스란 개념도 존재한다.

클래스, 객체, 인스턴스

클래스란, 객체를 만들어 내기 위한 추상적인 개념, 설계도 혹은 틀

객체란, 소프트웨어 세계에 구현할 대상, 클래스에 선언된 모양 그대로 생성된 실체

인스턴스란, 설계도를 바탕으로 소프트웨어 세계에 구현된 구체적인 실체

 

지금까지 클래스를 기반으로 현존하는 것이 객체라고 했는데 구체적인 실체가 갑자기 인스턴스란 말은 무엇인가. 사실 명확히 정의를 내리기 어렵다. OOP의 관점에서 객체가 메모리에 할당되어 실제 사용될 때 '인스턴스'라고 부른다. 이건 그냥 코드를 보며 이해하는 것이 나을 것 같다.

/* 클래스 */
public class Fruit {
  ...
}

/* 객체와 인스턴스 */
public class Main {
  public static void main(String[] args) {
    Fruit apple, banana; // '객체'

    // 인스턴스화
    apple = new Fruit(); // apple은 Fruit 클래스의 '인스턴스'(객체를 메모리에 할당)
    banana = new Fruit(); // banana은 Fruit 클래스의 '인스턴스'(객체를 메모리에 할당)
  }
}

 

정리를 해보자면,

과일 클래스의 속성을 가지고 선언되었을 때 객체(apple, banana)라고 부르고, 그 객체가 메모리에 할당되어 실제 사용될 때 인스턴스(apple, banana에 색, 크기들을 기입하고 사용하는 상태)라고 부른다.


✅ 객체 지향 프로그래밍 (Object Oriented Programming)이란?

우리가 주변의 실세계에서 사물을 인지하는 방식을 프로그래밍에 접목하려는 사상을 의미
프로그래밍에서 필요한 데이터를 추상화시켜 상태와 행위를 가진 객체를 만들고, 그 객체들간의 유기적인 상호작용을 통해 로직을 구성하는 프로그래밍 방법

위의 예시를 다시 생각해보면, 우리가 사물(사과)를 인지하는 방식은 각각의 속성의 값이 중요한 것이 아니라 특징과 기능 등을 인지함으로써 판단한다. 이것을 집단화, 분류화라고 하는데 이러한 인지 방식을 프로그래밍에 접목하려고 하는 것이다.

그렇다면 왜 객체 지향 방법을 쓰는 것일까? '가져와서 쓴다' 즉, 재사용이 가능하기 때문이다. 컴퓨터는 일일이 설명해주지 않으면 못알아 듣는다. 그래서 여러개의 사과라는 데이터를 만드려면 모든 속성을 지정해주어야 컴퓨터는 알아들을 것이다.

그런데 Class와 Object의 특성을 이용하면, Class에 미리 사과라는 어떠한 속성들만 지정해주고, 여러개의 사과를 만들때마다 값만 입력해주면 각각 다른 사과(Object)를 만들 수 있는 것이다. 


 객체 지향 프로그래밍(OOP)의 특징

객체 지향 프로그래밍에는 4가지 특징이 있다. 


1. 추상화 (Abstraction)

공통의 속성이나 기능을 묶어 이름을 붙이는 것

즉, 목적관련이 없는 부분을 제거하여 필요한 부분만을 표현하기 위한 것이 추상화이다.

객체와 클래스 관점에서보도록 하자.

객체들은 실제 그 모습이지만, 클래스객체들이 어떤 특징들이 있다고 정의하는 추상화된 개념인 것이다!

 

사과를 예시로 생각해보자.

우리 머리 속에는 사과라는 특징(클래스)이 있고, 우리가 보는 (실제하는)사과는 그냥 사과의 모습을 가지고 있다!

 

2. 캡슐화 (Encapsulation)

목적 : 코드를 재수정 없이 재활용하는 것

실제 프로그램 코드에서는 변수와 함수를 재활용하기에는 분산되어 있기 때문에 재활용이 매우 어렵다. 어디에 뭐가 있는지 일일이 찾기가 매우 어려우니깐..

 

그런데 캡슐화를 통해 관련된 기능과 특성을 한 곳에 모으고 분류하기 때문에 재활용이 원활해진다.

즉, 클래스라는 '캡슐'기능과 특성을 분류해서 넣는것이 캡슐화다.

추가적으로, 객체의 내용 중 숨기고 싶은 부분은 외부에서 접근할 수 없게 할 수 있다. 단지 해당 객체내의 함수에 의해서만 접근 가능하도록 하는 것이다.

 

(나만의 예시.. 무시해도 된다!)

사과를 예로 들면, 우리는 사과의 '색'이 빨간색이라고 인식하지, '크기'가 빨간색이라고 생각할 수는 없다. 이는 생각의 오류를 이끌어내기 때문에! 누가 내 머리를 세게 쳐서 사과의 '크기'가 빨간색이라고 생각하게 된다면 다른 사람들과 소통을 하는데 있어서 오류가 생길 것이다.)

 

3. 상속 (Inheritance)

부모클래스의 속성과 기능을 그대로 이어받아 사용할 수 있게하고, 기능의 일부분을 변경해야 할 경우 상속받은 자식클래스에서 해당 기능만 다시 수정(정의)하여 사용할 수 있게 하는 것

실제 세계에서 부모로부터 여러가지를 상속을 받는데, OOP에서도 가능하다.

OOP에서는 이를 부모 클래스, 자식 클래스라고 표현한다.

 

예를 들면, 사과라는 클래스 이외에 바나나 클래스, 딸기 클래스도 있다고 해보자.

그런데 사과, 바나나, 딸기는 과일에 해당한다! 과일이라는 클래스는 여러 속성들이 정의되어 있는데 사과, 바나나, 딸기 또한 이런 속성들을 갖고 있다. 하지만 많은 속성들이 다르기 때문에 좀더 깊게 분류해서 사과, 바나나, 딸기로 나눈 것이다.

 

즉, 과일이라는 부모 클래스는 사과, 바나나, 딸기라는 자식 클래스에 몇몇 공통적인 속성들을 물려준다. 이를 상속이라 하고, 과일 클래스와 (사과, 바나나, 딸기)클래스는 상속관계에 있다고 한다.

상속이 필요한 이유는 코드의 중복을 없애기 위함이다. 상속관계를 맺으면 자식 객체를 생성할 때 부모 클래스의 속성(과일)을 자동으로 물려받기 때문에 자식 클래스(사과, 바나나, 딸기)에서 또 정의할 필요가 없다.

 

 

4. 다형성 (Polymorphism)

하나의 변수명, 함수명 등이 상황에 따라 다른 의미로 해석될 수 있는 것

여기에는 오버라이딩(Overriding), 오버로딩(Overloading)이라는 개념을 추가할 수 있다.

오버라이딩 : 부모클래스의 메서드와 같은 이름, 매개변수를 재정의하는 것
오버로딩 : 같은 이름의 함수를 여러개 정의하고, 매개변수의 타입과 개수를 다르게 하여 매개변수에 따라 다르게 호출할 수 있게 하는 것

뭔말인가 하니,

과일 클래스에는 '맛'이라는 속성이 정의되어 있다고 생각해보자. 그러면 상속에 의해 자식 클래스인 사과, 자두에 '맛'이라는 속성이 자동으로 추가될 것이다. 그런데 사과와 자두는 맛이 다르다! 즉, 같은 '맛'속성이지만 실제 맛은 다르다.

 

다형성의 장점은, 같은 이름의 속성을 유지함으로서, 속성을 사용하기 위한 인터페이스를 유지하고, 메서드 이름을 낭비하지 않는다는 것이다! 즉 사과와 자두의 '맛'이라는 속성을 호출하기 위해서 굳이 flavorApple(), flavorPlum() 이라고 할 필요없이, 각 객체에서 단순히 flavor() 메서드만 호출하면 되는 것이다!

댓글