본문 바로가기

Back-End/Python

[Python][파이썬]객체 지향 프로그래밍(OOP)

~ 목차 ~

파이썬이 객체 지향 프로그래밍이라고 하는데 그게 무슨 말인지 의문이 생겼다.

그래서 찾아보니 프로그래밍 언어들 중 객체지향언어가 있고 절차지향언어가 있었다.

이 둘에 대해 알아보자. 

 

 

절차지향 프로그래밍 (Procedural Programming)

  • 개체를 순차적으로 처리하여 프로그램 전체가 유기적으로 연결되도록 만드는 프로그래밍
  • 절차 지향 프로그래밍은 프로시저 procedure를 기반으로 하는 프로그래밍 방법이다.
  • 예 : 자동차는 엔진, 차체, 핸들, 의자, 바퀴 순으로 차례대로 만들어져야 한다. 서로 분리되어도 안 되고, 순서가 틀려도 안 되는데 절차지향 프로그래밍 역시 이와 같다.
  • 장점 : 실행 속도가 빠르다.
  • 단점 : 유지보수의 어려움, 엄격하게 순서가 정해져 있어 비효율적
  • c언어

 

 

절차지향 프로그래밍의 단점을 해결하고자 객체지향 프로그래밍이 나왔다.

 

 

 

객체지향 프로그래밍 (Object-oriented programming)

    • 프로그램을 다수의 객체로 만들고, 이들끼리 서로 상호작용하도록 만드는 프로그래밍
    • 객체 지향 프로그래밍은 데이터와 함수를 하나의 객체로 묶어서 생각하는 방법이다.
    • 예 : 컴퓨터에 쓰이는 모든 부품(모니터, 키보드, 스피커 등)과 컴퓨터가 제공하는 모든 기능(화면이 켜짐, 소리가 남 등)이 전부 객체, 컴퓨터의 모든 부품을 적절히 연결하고 조립해서 컴퓨터가 제대로 작동하도록 만드는 것이 객체지향 프로그래밍이다.
    • 장점 : 재사용성(상), 생산성 증가, 자연스러운 모델링( 우리가 사는 세상을 닮음)
    • 단점 : 느린 개발 속도, 느린 실행 속도, 높은 난이도
    • 자바, c++, 파이썬 등

 

절차지향 vs 객체지향

 

 

 

요즘은 프로그래밍을 거의 객체지향 프로그래밍으로 한다.

유지보수가 좋다는게 크게 작용하는 것 같다.

그럼 객체지향 프로그래밍에서 클래스와 객체가 무엇인지? 객체지향 언어의 특성이 무엇인지? 알아보자.

 

 

클래스

  • 객체에 대한 설계도를 클래스class라고 한다.
  • 클래스란 특정한 종류의 객체들을 찍어내는 형틀 template또는 청사진이라고 할 수 있다.
  • 클래스로 부터 만들어지는 객체를 그 클래스의 인스턴스라고 한다.

 

 

객체

  • 객체(object) : 객체는 속성동작을 가진다.
    • 자동차는 메이커나 모델, 색상, 연식, 가격과 같은 속성(attribute)을 가지고 있다.
    • 자동차는 주행할 수 있고 방향을 전환하거나 정지할 수 있다. 이러한 것을 객체의 동작(action)이라고 한다.

 

 

객체지향 언어 특성

 

객체지향언어의 특징은 크게 캡슐화, 상속, 다형성, 추상화 4가지로 나눌 수 있다.

 

1. 캡슐화

  • 개발자로서 클래스의 객체를 가지고 작업할 때는 객체가 어떻게 내부적으로 속성을 저장하고 어떻게 메소드들이 구현되는지 알 필요가 없다.
  • 공용 인터페이스만 제공하고 구현 세부 사항을 감추는 것은 캡슐화(encapsulation)이라고 한다.
  • 데이터와 알고리즘을 하나로 묶어 하나의 캡슐처럼 만드는 것.
    이 특징 때문에 데이터와 코드의 형태를 외부에서 알 수 없다.

2. 상속

  • 부모가 자식에게 유전자를 물려주듯, 상위 클래스의 모든 것을 하위 클래스가 이어 받는 것.

 

3. 다형성

  • 상속과 연관된 개념으로, 하나의 객체가 다른 여러 객체로 재구성되는 것입니다.
  • 부모가 쌍둥이 자식을 낳으면 부모의 유전자가 두 명의 자식으로 재구성되는 것과 같은 이치.
  • 하지만, 그렇다고 해서 두 쌍둥이(재구성된 객체들)의 유전자가 부모(원 개체)의 유전자와 똑같다고 볼 수는 없다.
  • 자바의 오버로드, 혹은 오버라이드 다형성이 이 다형성을 드러내는 대표적인 예.

 

4. 추상화

  • 실존하는 객체의 여러 특성 중, 프로그램을 만드는데 필요한(공통적인) 부분만 파악해서 추출하고 필요하지 않은 것은 제거하는 것.

 

파이썬은 객체지향언어이다.

클래스는 객체의 설계도이며, 객체는 클래스의 인스턴스다.
클래스는 데이터(attributes)와 메서드(methods)로 구성되는데.
데이터는 객체의 상태를 나타내고, 메서드는 객체의 동작을 정의한다.
이러한 객체와 클래스를 사용하여 프로그램을 구조화하고 모듈화할 수 있다!

 

< 파이썬에서 클래스 생성하기 >

# 클래스
 class 클래스이름:
    def __init__():            #생성자
    def 메소드 이름(...):   #메소드

#모든 메소드에 사용 유무와 상관 없이 "self"파라미터가 첫번째로 들어 가야 한다.

class Counter:
    # count는 멤버변수, count = 0 이것 없어지는 추세
    count_a = 0
    def __init__(self): #생성자
        self.count = 0
        print('__init__')
    def increment(self): #메소드
        self.count += 1
        print('increment')
    def print_count(self): #메소드
        print(self.count)
a = Counter()
a.increment()
a.increment()
a.print_count()

결과

__init__
increment
increment
2

 

 

1. 멤버변수 접근

#멤버변수 접근 가능
a.count_a = 5
print(f'멤버변수접근 : {a.count_a}')

결과

멤버변수접근 : 5

 

 

2. 초기값 설정

# 초기값 설정 initValue = 0
class Counter():
    def __init__(self, initValue = 0):
        self.count = initValue
    def increment(self):
        self.count += 1
    def print_count(self):
        print(self.count)
a = Counter()
a. increment()
a.print_count()

결과

1

 

 

b = Counter(100)
b.increment()
b.print_count()

결과

101

 

 

3. default값 설정 : 변수 앞에  _ _ 또는 _ 붙이기(접근제한은 _ _ 사용)

class Tv:
    def __init__(self):
        # default값 설정 변수 앞에  __또는_ 붙이기(접근제한은 __ 사용)
        self.__channel = 0
        self._volume = 0
        self.__on = 'on'
        self._off = 'off'
    
    def show(self):
        print(self.__channel, self._volume, self.__on)
        
    def set_channel(self, channel):
        # 지문인식 등록 된 사람 지문 인지 검사
        self.__channel = channel

 

 

  • default값 설정 : _ 사용
a = Tv()
a.show()
a._off

결과

0 0 on
'off'

 

  • default값 설정 : __ 사용 (접근제한자)
a = Tv()
a.show()
a.__on

결과

AttributeError: 'Tv' object has no attribute '_on'


※접근제한자 붙은 멤버변수에 접근하면 error가 난다!

 

 

4. 최종 Tv class (set, get메소드 만들기)

class Tv:
    def __init__(self):
        # default값 설정 변수 앞에  __또는_ 붙이기(접근제한은 __ 사용)
        self.__channel = 0
        self._volume = 0
        self.__on = 'on'
        self._off = 'off'
    
    def show(self):
        print(self.__channel, self._volume, self.__on)
    
    #채널    
    def set_channel(self, channel):
        # 지문인식 등록 된 사람 지문 인지 검사
        if 2 < channel and 99 > channel:
            #channel 값이 3에서 98 사이에 있을 때 True. 2와 99는 포함되지 않음. 
            self.__channel = channel
        
    def get_channel(self):
        return self.__channel
    
    #여기서도 get,set메소드 자동으로 생성해주는 기능 있음(따로 알아보기)
    #켜기
    def set_on(self, on):
        self.__on = on
        
    def get_on(self, on):
        return self.__on

 

a = Tv() 
a.set_channel(100)
a.show()

결과

0 0 on

 

a.set_channel(95)
a.show()

결과

95 0 on

 

5. 함수 안에 함수 사용 안하는게 좋다.

 

자바에서 class안에 class(이너 클래스)는 안 쓰는게 좋았다.
따라서 메소드 안에 메소드도 안 쓰는게 좋다.

 

def Tv_fun():
    channel = 0
    volume = 0
    on = 'on'
    
    def set_channel(channel):
        channel = channel
    
    def get_channel():
        return channel
b = Tv_fun()
b.set_channel(8)

결과

AttributeError: 'NoneType' object has no attribute 'set_channel'

 

※오류나는 이유 : 함수에서 선언된 변수를 외부에서 가져다 쓸 수 없음

 

 

 

5. 입출금 클래스 만들기

  • 은행 계좌
    • 잔액(balance) 상태 필요
    • 저금(deposit) 행동, 인출(withdraw) 행동 필요
  • 전달 받은 금액을 잔액에 누적한다.
    입금 금액의 범위가 0보다 커야 한다.
     1일 입출금 한도, 최대 입출금액이 한도를 초과 하지 않아야 한다.(1억)
     (옵션) 총 잔액을 반환 한다.
  • 모델링 :UML사용하면 좋음
class BankAccount:
    def __init__(self):
        self.__balance = 0
    
    def deposit(self, amount):
        if amount > 0 and 100000000 > amount:
            self.__balance += amount
            print(f'{amount}를 입금하셨습니다. \n 잔액은 총 {self.__balance}입니다.')
            return self.__balance
        else:
            print('1일 입금 한도금액을 초과하였습니다.')
            
    def withdraw(self, amount):
        if amount > 0 and 100000000 > amount:
            self.__balance -= amount
            print(f'{amount}를 출금하셨습니다. \n 잔액은 총 {self.__balance}입니다.')
            return self.__balance
        else:
            print('1일 출금 한도금액을 초과하였습니다.')
    
    def my_account(self):
        print(f'현재 나의 잔액은 {self.__balance}입니다.')
a = BankAccount()
a.deposit(100000)
a.withdraw(50000)

결과

100000를 입금하셨습니다. 
 잔액은 총 100000입니다.
50000를 출금하셨습니다. 
 잔액은 총 50000입니다.

 

50000(return값)

 

 

a.deposit(1000000000)

결과

1일 입금 한도금액을 초과하였습니다.

 

 

재사용성: 클래스를 사용하면 비슷한 기능을 하는 코드를 여러 곳에서 재사용할 수 있다. 클래스의 인스턴스를 생성하여 다양한 상황에서 동일한 코드를 사용할 수 있다.

b = BankAccount()
b.deposit(10000)
b.withdraw(2000)
b.my_account()

 

결과

10000를 입금하셨습니다. 
 잔액은 총 10000입니다.
2000를 출금하셨습니다. 
 잔액은 총 8000입니다.
현재 나의 잔액은 8000입니다.

 

 

728x90