[CS] OOP ?!

객체 지향 프로그램(Objects Oriented Programming)

1. 개념

  • 객체 지향 프로그램(Objects Oriented Programming)
  • 비교개념은 절차 지향 프로그래밍
  • 프로그램을 객체(object)라는 기본 단위로 나누고 객체들의 상호작용으로 기능들을 구현하는 방식
  • Key Point
    • 독립적인 객체들의 집합을 통하여 객체들이 서로 상호작용을 하는 구조로 전체 프로그램이 구현될 수 있도록 하는 것
    • 로직구조를 더하기 위해 OOP를 사용

2. 사용이유

  • 절차 지향 방식 -> 데이터를 중심으로 함수 구현, 순차적인 처리 중요, C언어
  • 객체 지향 방식 -> 기능을 중심으로 함수 구현

  • OOP 사용의 핵심 이유 : 코드의 구조화
    • 유지보수 용이 : 기능별로 구현되어 있기 때문에 일부가 고장나도 그 해당 부분만 고치면 됨
    • 재활용 용이 : 정의한 class를 상속하고 확장하여 재사용할 수 있음
    • 가독성 좋아짐

3. Class & Object & Instance

1. 클래스(class)

1) 개념

  • 객체를 생성하기 위한 설계도
  • 클래스를 잘 이해하는 것이 OOP의 기본
  • ex) Car라는 부류가 클래스(큰 개념, 범주)

    Car의 instance(실체)가 렉서스, bmw, 벤츠, 현대라는 객체인 것

2) 구성

  • Class = Property + Method
  • Property(속성) : 해당 entity를 표현하는 data = 변수 = 명사
  • Method(기능) : 해당 entity가 가지고 있는 기능들 = 함수 = 동사

2. 객체(Object)

  • 클래스를 통해 정의된 설계도로 만들어진 프로그램
  • 객체는 고유한 성격을 지니기 때문에 동일한 클래스로 만들어진 객체라도 다른 객체의 영향을 받지 않는다
  • 객체는 클래스의 constructor 메소드로 생성된다.

3. 인스턴스(Instance)

  • 클래스로 만든 객체를 인스턴스라고도 함
  • 객체가 개념이라면 인스턴스는 실체
  • 인스턴스라는 말은 특정 객체가 어떤 클래스의 객체인지 관계를 위주로 설명할 때 사용
  • ex) 현대는 그 자체로는 인스턴스라기 보다는 객체이고,

    class와의 관계에서 보면 Car의 객체라고 말하기보단 Car의 인스턴스라고 함

4. The Four Pilars of OOP

1. Encapsulation (캡슐화)

  • 관련있는 변수와 함수를 하나의 단위로 묶는 것
  • 자동차와 관련된 변수와 함수가 묶여있는 클래스 자체가 캡슐화의 예시
class Car:
    def __init__(self, model, price, color):
        self.model = model
        self.price = price
        self.color = color

    def drive(self, speed):
        if speed > 100:
            return "SPEEDING VIOLATION"
        else:
            return "DRIVE CAREFULLY"

Information Hiding(정보 은닉)

  • 속성이나 메소드같이 객체가 소유하는 것들을 다른 객체에 공개하지 않고 숨기는 것
  • 외부 객체가 특정 객체의 데이터화 함수를 직접 접근하여 사용하거나 변경하지 못하므로 유지 보수와 소프트 웨어 확장시 오류를 최소화
  • 속성과 메소드의 공개 범위를 access modifier(접근 제어자) 로 결정
    • public : 공개
      • 해당 클래스의 객체, 상속받는 클래스의 객체, 그리고 외부 객체 모두 다 접근 가능
    • private : 숨김
      • Private으로 지정된 property나 메소드는 해당 클래스의 객체 내부에서만 접근 가능
      • 외부 객체는 접근이 막혀있음
      • 상속받는 sub class도 직접적인 접근은 할 수 없고 상속받지 아니한다.
    • protected : 숨김
      • 외부 객체는 접근이 막혀있음
      • 상속받는 sub class는 접근 할 수 있고 상속 받는다.

2. Abstraction (추상화)

  • 객체들의 공통 특징(property, method)을 뽑아 하나의 클래스로 표현하는 것
  • 객체의 관점에서 클래스를 정의하는 것
  • 사자, 곰, 말 -> 각각 객체

    이 객체들을 공통된 특징인 동물이나 생물로 묶는 것이 추상화

3. Inheritance (상속성)

  • 자식클래스(Sub Class)가 부모클래스(Base Class, Super Class)로부터 PropertyMethod들을 상속받을 수 있는 특성
class Car:
    def __init__(self, model, price, color):
        self.model = model
        self.price = price
        self.color = color

    def drive(self, speed):
        if speed > 100:
            return "SPEEDING VIOLATION"
        else:
            return "DRIVE CAREFULLY"

class Taxi(Car):
    def take_passengers(self, passengers):
        if passengers > 4:
            return "5명 이상 못 탐"
        else:
            return "출발~"

taxi1 = Taxi("기아", "3,000만원", "orange")
print(taxi1.take_passengers(7)) 
# 5명 이상 못 탐

print(taxi1.drive(120))
# SPEEDING VIOLATION 🔵
  • Taxi 클래스는 자신의 고유 Method를 사용할 수 있는 것은 물론 Car 클래스를 상속받았기 때문에 Car 클래스 안의 Property(model, price, color) 와 Method(drive) 모두를 사용할 수 있다🔵
  • 상속성을 사용하면 자식클래스에서 불필요하게 다시 정의할 일 없이 부모클래스의 코드를 재사용가능하기 때문에 중복을 방지할 수 있다
  • Overriding : 부모클래스의 메소드를 그대로 상속받지 않고 재정의해서 사용할 수 있는 기능

4. Polymorphism (다형성)

  • 하나의 형태가 다양한 유형으로 나타날 수 있는 특성
  • Overriding처럼 부모클래스의 메소드가 자식클래스에서 다양한 기능으로 나타날 수 있는 것도 한 예시
  • Overloading : 메소드의 이름은 같지만 매개변수가 다름
    • python 과 javascript는 overloading 함수를 지원하지 않음
    • ex) sum 이라는 같은 이름의 함수가 매개변수의 개수와 타입에 따라 각기 다른 3개의 메소드로 구현되고 있다
public class Math {
  
    public int sum(int x, int y)
    {
        return (x + y);
    }
  
    public int sum(int x, int y, int z)
    {
        return (x + y + z);
    }
  
    public double sum(double x, double y)
    {
        return (x + y);
    }
  
    public static void main(String args[])
    {
        Math math = new Math();
        System.out.println(math.sum(1, 2));
        System.out.println(math.sum(3, 4, 5));
        System.out.println(math.sum(7.7, 8.8));
    }
}
  • Duck Typing : “만약 어떤 것이 오리처럼 생겼고, 오리처럼 헤엄치고, 오리처럼 꽥꽥거린다면 그건 오리라고 봐야 한다"라는 오리 실험에서 유래된 것으로 동일한 변수와 메소드를 가지고 있는 객체는 동일한 타입으로 간주하는 typing 방법
  • 서로 아무 상관없는 세 클라스 Truck, Bus, RaceCar는 모두 drive 메소드를 제공하기 때문에 Duck Typing 개념에 의하여 drive_car 함수 입장에서는 동일한 객체로 간주될 수 있다는 것이다.
class Truck:
  def drive(self):
    print("Driving Truck")

  def stop(self):
    print("Stoping Truck")


class Bus:
	def drive(self):
		print("Driving Bus")

	def stop(self):
		print("Stoping Bus")


class RaceCar:
	def drive(self):
		print("Driving RaceCar")

	def stop(self):
		print("Stoping RaceCar")


def drive_car(car):
	car.drive()


truck = Truck()
bus = Bus()
race_car = RaceCar()

drive_car(truck) # Driving Truck
drive_car(bus) # Driving Bus
drive_car(race_car) # Driving RaceCar
  • Polymorphism(다형성) 이 중요한 이유

    polymorphism을 통해서 포괄적인(generic) 인터페이스 제공이 가능해지기 때문이다. 위 duck typing 코드 예제에세도, drive_car 함수는 실제 input으로 들어오는 객체의 타입이나 구현 내용이나 실행 로직에 대해서 확인하거나 인지할 필요가 없다. drive 메소드만 가지고 있다면 실행이 가능하기 때문이다. 그러므로 polymorphism을 통해 굉장히 유연하고 간단한 인터페이스 및 로직 구현이 가능해진다.

좋은 웹페이지 즐겨찾기