개발 상식

객체 지향 프로그래밍

컴공누누 2023. 11. 17. 22:52

객체 지향 프로그래밍이란?

예전에는 비구조적 프로그래밍을 통한 코딩을 해나갔다. 비구조적 프로그래밍은 말 그대로 순차적으로 코딩해나가는 것을 의미한다. 만약 이전에 작성했던 코드가 필요하면 goto문을 활용하여 그 곳으로 이동하게 된다. 하지만 규모가 커지면 커질수록 뒤죽박죽이 되고 코드가 어떻게 연결되어 있는지 파악하는것 조차 힘들게 되버린다.

이런 문제점을 해결하기 위하여 객체지향 프로그래밍이 탄생하게 된다.

객체 지향 프로그래밍 (Object-Oriented Programming, OOP)은 컴퓨터 프로그램을 명령어의 목록으로 보는 시각에서 벗어나 여러 개의 독립 된 단위인 객체들의 모임으로 파악하고자 하는 것이다.

기본 구성 요소

  • 클래스(Class): 객체 지향 프로그래밍에서 특정 객체를 생성하기 위해 변수메서드를 정의하는 일종의 틀이다.

  • 객체(Object): 객체 지향 프로그래밍에서 객체는 클래스의 인스턴스이다. 클래스에서 정의한 것을 토대로 메모리에 할당되고 데이터 또는 식별자에 의해 참조되는 공간을 말한다.

  • 메서드(Method): 객체 지향 프로그래밍에서 객체와 관련된 서브 루틴이자 클래스가 갖고 있는 기능이다. 데이터와 멤버 변수에 대한 접근 권한을 갖는다.

인스턴스

  • 설계도를 바탕으로 소프트웨어 세계에 구현된 구체적인 실체를 말한다.

  • 실체화된 인스턴스는 메모리에 할당된다.

class Animal(
    val leg: Int,
    val isWing: Boolean
)

fun main() {
    val dog = Animal(leg = 4, isWing = false)
    val duck = Animal(leg = 2, isWing = true)
}

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

객체 지향 프로그래밍의 특징은 기본적으로 추상화, 상속, 캡슐화, 다형성의 네가지 특징을 말한다.

1. 추상화

추상화의 사전적 정의는 여러 가지 사물이나 개념에서 공통되는 특성이나 속성을 추출하여 파악하는 것을 의미한다.
객체 지향 프로그래밍에서 추상화의 의미는 객체의 공통적인 속성과 기능을 추출하여 정의하는 것을 의미한다.

abstract class Car {
    abstract val maxSpeed: Int
    abstract val maxPeople: Int

    abstract fun startCar()
}

class Audi : Car() {
    override val maxSpeed: Int = 305
    override val maxPeople: Int = 5

    override fun startCar() {
        println("버튼을 눌러 시동 켜기")
    }

}

class Starex : Car() {
    override val maxSpeed: Int = 110
    override val maxPeople: Int = 11

    override fun startCar() {
        println("차키를 돌려 시동 켜기")
    }

}

코드의 예시를 보면 Car 클래스는 최고 속도와 최대 수용 인원 그리고 시동을 거는 방법으로 이루어져 있다.

Audi 클래스의 경우 최고 속도는 305km이고 최대 수용 인원은 5명이며 버튼을 눌러 시동을 거는 반면 Starex 클래스는 최고 속도는 110km이고 최대 수용 인원은 11명이며 차키를 돌려 시동을 켜는 방식이다.

Car 클래스에 내용을 바탕으로 다른 클래스의 내용을 구체화하기만 하면 되기 때문에 추상화를 해놓는 것이 유리하다. 왜냐하면 다른 차들도 이러한 속성을 갖고 있기 때문에 다른 차 클래스를 추가하면 되기 때문이다.

2. 상속

상속은 기존의 클래스를 새로운 클래스에 이식하는 것을 의미한다. 새로운 클래스는 기존의 클래스의 변수와 함수를 이용할 수 있고 새로운 내용을 추가 할 수 있다.

open class Mp3() {
    open fun nextSong() {
        println("다음 곡으로 이동")
    }
    open fun beforeSong() {
        println("이전 곡으로 이동")
    }
    open fun controlVolume() {
        println("볼륨 조절")
    }
}

class SmartPhone() : Mp3() {
    override fun nextSong() {
        super.nextSong()
    }

    override fun beforeSong() {
        super.beforeSong()
    }

    override fun controlVolume() {
        super.controlVolume()
    }

    fun search() {
        println("검색 기능")
    }
}

위의 코드를 보면 Mp3 클래스에는 3개의 함수가 존재하고 Mp3 클래스를 상속 받은 SmartPhone 클래스는 기존의 함수들을 모두 상속받으면서 search 함수가 추가된 것을 볼 수 있다.

3. 캡슐화

캡슐화는 클래스 안에 서로 연관있는 속성과 기능들을 하나의 캡슐로 만들어 데이터를 외부로부터 보호하는 것을 말한다.

객체 지향 프로그래밍에서 캡슐화를 하는 이유로는 데이터 보호데이터 은닉 이렇게 두 가지가 있다.

코틀린의 접근 제어자의 접근 범위를 표로 나타내면 다음과 같다.

  • 클래스

    변경자 접근 범위
    public 어느 위치에서든 참조 가능
    private 선언한 클래스 내부에서만 참조 가능
    internal 같은 모듈 안에서만 참조 가능
    protected 선언한 클래스 내부 + 서브 클래스에서 참조 가능
  • 패키지

    변경자 접근 범위
    public 어느 위치에서든 참조 가능
    private 선언한 파일 내부에서만 참조 가능
    internal 같은 모듈 안에서만 참조 가능
    protected 사용 불가

4. 다형성

다형성은 어떤 객체의 속성이나 기능이 상황에 따라 여러 가지 형태를 가질 수 잇는 성질을 말한다.
객체 지향 프로그래밍에서는 오버라이딩오버로딩이라는 개념으로 불린다.

  • 오버로딩

오버로딩은 같은 이름이지만 서로 다른 매개변수 형식을 가진 메소드를 여러개 정의할 수 있는 방법을 말한다.

class Add() {
    fun add(num1: Int, num2: Int): Int{
        return num1 + num2
    }

    fun add(num1: Float, num2: Float): Float{
        return num1 + num2
    }

    fun add(num1: String, num2: String): String{
        return num1 + num2
    }
}

위의 코드를 살펴 보면 다 같은 Add 함수이지만 매개변수와 반환 값이 전부 다르다. 이처럼 함수 이름은 같지만 다른 매개변수 형식을 가진 메소드를 정의하는 방식을 오버로딩이라고 한다.

  • 오버라이딩

오버라이딩은 부모 클래스가 가지고 있는 기능을 필요에 따라 자식 클래스에서 변경 혹은 재정의 하는 방법이다.

open class Animal() {
    open fun crySound() {
        println("울음 소리")
    }

    open fun type() {
        println("동물 종류")
    }
}

class Tiger() : Animal() {
    override fun crySound() {
        println("어흥")
    }

    override fun type() {
        println("포유류")
    }
}

class Duck() : Animal() {
    override fun crySound() {
        println("꽥꽥")
    }

    override fun type() {
        println("조류")
    }
}

부모 클래스인 Animal에서는 각각 crySound 함수와 type 함수가 있고 울음 소리와 동물 종류를 출력하는 내용을 담고 있다.

자식 클래스인 Tiger 클래스에서는 부모 클래스의 함수 내용을 재정의하여 crySound는 어흥을 출력하고 type은 포유류를 출력한다.

마찬가지로 Duck 클래스에서도 함수를 재정의하여 부모 클래스와는 다른 출력 결과를 볼 수 있다.

이처럼 부모 클래스가 가지고 있는 기능을 필요에 따라 자식 클래스에서 변경 혹은 재정의 하는 방법을 오버라이딩이라고 한다.

면접 예상 질문

  1. 객체 지향 프로그래밍의 네 가지 특징을 말해보세요.
  2. 객체 지향 프로그래밍의 장단점을 설명해보세요.
  3. 객체가 무엇인지 설명해보세요.
  4. 클래스와 인스턴스는 무엇인지 설명해주세요.
  5. 캡슐화가 무엇인지 설명해주세요.

참고 URL

객체 지향 프로그래밍의 특징
객체 지향 프로그래밍 면접 질문
객체 지향 프로그래밍에 대한 것

'개발 상식' 카테고리의 다른 글

RESTful API란?  (0) 2023.12.08
SOLID 원칙  (0) 2023.11.19