Python 15 OOP 객체 지향 프로그래밍

김민호·2021년 12월 8일
0

Python

목록 보기
16/16
post-thumbnail

OOP란?

개념

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

사용이유

  • 절차 지향 방식
    데이터를 중심으로 함수 구현, 순차적인 처리 중요, C언어
  • 객체 지향 방식 -> 기능을 중심으로 함수 구현
  • 핵심 : 코드의 구조화
  • 유지보수 용이 : 기능별로 구현되어 있기 때문에 일부가 고장나도 그 해당 부분만 고치면 됨
  • 프로그램 (확장) 용이 : 새로운 것 추가가 쉬움
  • 재활용 용이 : 정의한 class를 상속하고 확장하여 재사용할 수 있음
  • 가독성 좋아짐

Class & Object & Instance

1. 클래스(class)

개념

  • 객체를 생성하기 위한 설계도인 클래스를 잘 이해하는 것이 OOP의 기본
  • 객체와 클래스는 독립적인 entity를 나타내야 한다

구성

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

2. 객체(Object)

  • 클래스를 통해 정의된 설계도로 만들어진 프로그램
  • 객체는 다른 객체의 영향을 받지 않는다
  • 객체는 클래스의 constructor 메소드로 생성된다.

3. 인스턴스(Instance)

  • 클래스로 만든 객체를 인스턴스라고도 함
  • 객체가 개념이라면 인스턴스는 실체

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 : 정보를 숨겨주는 기능으로써, 캡슐화되어 있는 코드들을 외부 접근으로부터 보호해서 객체가 훼손될 위험을 방지하는 기능

2. Abstraction (추상화)

  • 객체들의 공통 특징(property, method)을 뽑아 하나의 클래스로 표현하는 것

3. Inheritance (상속성)

  • 자식클래스(Sub Class)가 부모클래스(Base Class, Super Class)로부터 Property와 Method들을 상속 받을 수 있는 특성
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) 모두를 사용할 수 있다🔵

  • 상속성을 사용하면 자식클래스에서 불필요하게 다시 정의할 일 없이 부모클래스의 코드를 재사용가능하기 때문에 중복을 방지할 수 있다

  • override : 부모클래스의 메소드를 그대로 상속받지 않고 재정의해서 사용할 수 있는 기능

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 "가자가자"
    
    def drive(self, speed):
        if speed > 80:
            return "택시는 80km/h 이상 금지"
        else:
            return "안전운전"

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

print(taxi1.drive(90))
# 택시는 80km/h 이상 금지

4. Polymorphism (다형성)

  • 하나의 형태가 다양한 유형으로 나타날 수 있는 특성
  • override 처럼 부모클래스의 메소드가 자식클래스에서 다양한 기능으로 나타날 수 있는 것도 한 예시
  • 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)
drive_car(bus)
drive_car(race_car)

# Driving Truck
# Driving Bus
# Driving RaceCar
  • Polymorphism 이 중요한 이유 : polymorphism을 통해서 포괄적인(generic) 인터페이스 제공이 가능해지기 때문이다. 위 duck typing 코드 예제에세도, drive_car 함수는 실제 input으로 들어오는 객체의 타입이나 구현 내용이나 실행 로직에 대해서 확인하거나 인지할 필요가 없다. drive 메소드만 가지고 있다면 실행이 가능하기 때문이다. 그러므로 polymorphism을 통해 굉장히 유연하고 간단한 인터페이스 및 로직 구현이 가능해진다.
profile
개발자로서의 삶은 https://velog.io/@maxminos 에서 기록하고 있습니다 😀

0개의 댓글