스터디/파이썬 스터디 강의자료

[3팀/김규리] 8차시 파이썬 스터디 - 객체 지향 프로그래밍

kyuree 2023. 5. 18. 15:25

8차시_과제_객체지향프로그래밍.pdf
6.84MB
8차시_객체지향프로그래밍_과제답안.pdf
0.18MB
8차시_강의안_객체지향프로그래밍.pdf
11.47MB

#1. 객체 지향 프로그래밍의 이해

객체 지향 프로그래밍을 배우는 이유


객체 지향 프로그래밍의 개념은 왜 사용할까?

  • 함수처럼 여러 사람과 프로그램 개발할 때
  • 다른 사람이 작성한 코드를 어떻게 사용하면 좋을지 고민할 때
  • 남이 만든 코드를 재사용하고 싶을 때 대표적인 방법!

개념

  • 어떤 기능을 수행하는 하나의 단일 프로그램을 객체라고 하는 코드로 만들어 다른 사람이 재사용할 수 있도록 함

객체와 클래스


  • 객체속성(attribute)과 행동(action)으로 구성
    • 속성 → 변수로 정의
    • 행동 → 함수로 정의

예시) 인공지능 축구 프로그램

  • 게임 구성 단위
    • 심판, 선수, 팀 → 각각이 객체가 됨

 

  • 객체는 한 프로그램에서 여러 개 사용 가능
  • 따라서 객체들을 위한 설계도 제작 필요 ⇒ 클래스(class)
    • 각 객체의 개수?
    • 어떤 객체가 필요할까?
  • 실생활에 존재하는 실제적 물건 및 개념을 의미
  • 클래스
    • [객체]축구 선수 → 선수 이름 & 포지션 & 소속팀
    • 이런 클래스를 바탕으로 실제 값이 할당된다면 ⇒ 인스턴스(instance)
  • 객체가 가져야 할 기본 정보 담은 코드, 일종의 설계도 코드
  • 인스턴스

 

  • 예시) 붕어빵틀 & 붕어빵
    • 붕어빵틀로 여러 개의 붕어빵 만들 수 있다
    • [클래스] 붕어빵틀 , [인스턴스] 붕어빵
    • 잘 만든 붕어빵틀 있으면 다양한 붕어빵 만들 수도 있다!
    • ⇒ 잘 만든 클래스 코드가 있다면, 이것으로 다양한 종류의 인스턴스 생성할 수 있다~

#2-1. 파이썬의 객체 지향 프로그래밍

클래스 구현하기


  • 클래스 선언을 위한 기본 코드 템플릿

  • 설명
    • 맨 앞 → 클래스 예악어인 class
    • 중간 → 만들고자하는 클래스 이름
    • 마지막 → 상속받아야 할 다른 클래스 이름
      • 상속? → 기존 클래스의 특징 그대로 이어받아 사용하는 것
  • 클래스 작명 방법

  • 속성의 선언
    • 선언 → 클래스의 속성 추가
    • init()
      • 속성에 대한 정보 선언할 때 사용하는 예약 함수
      • +) 파이썬의 예약 함수
        • init(), str, add
        • 약손된 형태의 작업을 수행해줌

  • 함수의 선언
    • 클래스의 다양한 동작 정의
    • 코드

  • _의 쓰임
    • 개수에 다라 쓰임이 다름
    • ‘_’ 1 개 → 이후로 쓰이지 않을 변수에 특별한 이름 부여하고 싶지 않을 때

인스턴스 사용하기


  • 인스턴스
    • 클래스에서 실제적인 데이터가 입력되어 사용할 수 있는 형태의 객체
  • 클래스에서 인스턴스 호출 방법
    • 클래스 이름 호출
    • 정의한 ‘init’의 매개변수에 맞춰 값 입력
    • 함수의 초깃값 지정과 같은 개념
    • self에 어떠한 값도 할당하지 않음

  • #14
    • 인스턴스 새롭게 생선
    • jinhyun → name, position, back_mimber에 각각 Jinhyiin, MF, 10이 할당됨
  • 함수 호출할 때도 인스턴스 이름과 함수명 사용

클래스를 사용하는 이유


  • 자신의 코드를 다르 사람이 손쉽게 사용할 수 있도록 설계하기 위함
  • 하나의 객체로 생성하기가 더 좋음
  • 코드를 좀 더 손쉽게 선언 가능

  • 주의할 점
    • 객체 지향 프로그래밍 만능주의를 조심하자!
      • 모든 새로운 방법으로 시도하기 보다 필요방법을 적재적소에 사용하여 문제를 해결하자

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

상속


  • 무언가를 내려받는 것을 의미
  • 부모 클래스에 정의된 속성과 메서드를 자식 클래스가 물려받아 사용

  • 설명
    • 먼저 Person 클래스를 생성
      • Person 클래스에는 생성자 인수를 만들어 name과 age에 관련된 정보를 입력할 수 있도록 함
    • Korean 클래스를 만듦 → Person 클래스를 상속받음
      • class Korean(Person)과 같이 작성하면 간단히 상속가능.
      • pass → 별도의 내용 없이 클래스만 존재한다는 뜻
      • 즉, 별도의 내용이 없는 Korean 클래스 인스턴스를 만든 것
      • Korean 클래스는 별도의 생성자는 없지만, Person 클래스가 가진 생성자를 그대로 사용하여 인스턴스를 만듦
      • Person 클래스에서 생성한 변수를 그대로 사용가능
      • 이러한 객체 지향 프로그래밍의 특징을 상속이라고 함
  • 상속을 도표로 표현
    • 사각형이 클래스
    • 화살표는 각 클래스 의 상속 관계
      • 즉, Person 클래스를 Employee가 상속받고, 이 클래스를 다시 한번 Manager, Staff. Hourly 등이 상속받는 것

먼저 부모 클래스가 Person

  • name, age, gender에 대해 변수를 선언
  • about_ me 함수를 사용하여 생성된 인스턴스가 자신을 설명할 수 있도록함
  • 사실 str() 함수에 들어가도 되는 클래스이지만 임의의 about_me 클래스를 생성

다음으로 상속받는 Employee 클래스

  • Person 클래스가 단순히 사람에 대한 정보를 정의 → Employee 클래스는 사람에 대한 정의와 함께 일하는 시간과 월급에 대한 변수를 추가
  • init() 함수를 재정의
    • 이때 부모 클래스의 __init () 함수를 그대로 사용하려면 별도의 init() 함수를 만들지 않아도 됨
    • 하지만 기존 함수를 사용하면서 새로운 내용을 추가하기 위해서는 자식클래스에 init() 함수를 생성할 때 super().init(매개변수) 라고 입력
      • 여기서 super()는 부모 클래스를 가리킴
      • ⇒ 즉, 부모 클래스의 init() 함수를 그대로 사용한다는 뜻
    • 그 아래에는 자식 클래스에서 필요한 새로운 변수를 추가하면 됨
    • 이러한 함수의 재정의를 오버라이딩 overriding이라고 함
    • 오버라이딩
      • 상속 시 함수 이름과 필요한 매개변수는 그대로 유지 → 함수의 수행 코드를 변경하는 것
      • 같은 방식으로 about_me() 함수가 오버라이딩된 것을 확인할 수 있음
      • Person과 Employee에 대한 설명을 추가한 것
    • 위 코드들은 설명의 용이성을 위해 텍스트 형태의 설명만 추가하였지만 실제로는 프로그램에 사용하기 위한 다양한 기능이 추가될 수 있음
      • do_work처럼 자식 클래스에만 필요한 새로운 함수를 생성할 수 있음
      • 앞서 설명했듯이 자 식 클래스는 부모 클래스보다 더 상세한 일
      • 따라서 자식 클래스가 새로운 기능을 수행할 수 있도록 코드를 작성
    • 파이썬에서는 이외에도 다양한 상속 기능을 지원
      • 예를 들어, 1개 이상의 클래스 특징을 상속하는 다중상속을 지원하기도 함

다형성


같은 이름의 메서드가 다른 기능을 하는 것을 말함

  • 예를 들어, about_me라는 함수를 부모 클래스와 자식 클래스가 서로 다르게 구현했는데, 이것도 일종의 다형성이다.

그렇다면 다형성을 사용하는 이유는 무엇일까?

  • 객체 지향 프로그래밍은 다른 사람의 코드를 쉽게 재사용하기 위해 사용
  • 이를 위해서는 내부적인 구현 과정은 잘 모르더라도 그 함수나 클래스의 역할은 명확히 알 필요 있음
  • 인터넷에서 데이터를 모으는 프로그램을 크롤러 crawler라고 하는데.
  • 이번에는 뉴스를 모으는 크롤러를 만들어보면서 설명
    • 먼저 부모 Crawler 클래스를 만들고 do_crawling이라 는 함수를 생성
    • 그리고 Crawler 클래스를 상속시켜 NaverCrawler와 DaumCrawler를 만듦
    • 이제 두 자식 클래스는 모두 do_crawling 함수를 갖게 됨
    • 같은 이름이지만 구현 내용은 다름
    • 각각 클래스에서 구현되는 내부 로직에 차이가 있음
      • 이를 함수의 다형성이라고 함.
    • 여기서 Crawler 클래스들의 do crawling 함수는 각각 네이버와 다음에서 뉴스를 가져오는 역할
    • 해당 클래스의 사용자는 데이터를 어떻게 가져오는지 모르지만 결과는 두 클래스 모두 같다는 것을 알 수 있음

  • 해당 클래스의 사용자 입장에서는 함수의 이름만 알면 같은 형태로 사용할 수 있지만. 클래스 의 개발자 입장에서는 내부적인 구현을 각 클래스별 다르게 개발할 필요가 있음
  • 이를 다형성 이라고 하는데, 다형성을 사용하면 프로그램을 작성할 때 사용자가 좀 더 쉽게 클래스를 사용 할 수 있음.
  • 아래 [코드 10-6]은 의사=pseudo-code로 실제 작동되지는 않고 단지 다형성을 설명 하기 위해 만든 코드
  • 코드

→ 부모 클래스는 Animal

  • Cat과 Dog는 Animal 클래스를 상속받음
  • 핵심 함수는 talk → 각각 두 동물 클래스의 역할이 다른 것을 확인
  • Animal 클래스는 아직 설명하지 않았지만 NotlmplementedError라는 클래스를 호출
    • 이 클래스는 자식 클래스에만 해당 함수를 사용할 수 있도록 함
    • 따라서 두 클래스가 내부 로직에서 같은 이름의 함수를 사용하여 결과를 출력하도록 함
    • 정의된 모든 클래스는 15〜 17행과 같이 사용가

가시성


객체의 정보를 볼 수 있는 레벨을 조절하여 객체의 정보 접근을 숨기는 것

  • 이 특징은 다양한 이름으로 불림
    • 좀 더 중요한 핵심 개념은 캡슐화encapsulation와 정보 은닉 information hiding
  • 파이썬에서는 객체의 재사용을 위해 각 객체가 무슨 역할을 하는지 알아야 함
    • .구현의 세부적인 내용을 모두 알 필요는 없음. 단지 사용하는 방법만 알면 됨.
    • ⇒ 즉. 객체의 매개변수 인터페이스만 명확히 알면 사용할 수 있음
    • 이러한 개념을 캡슐화라고 하며. 객체의 세부 내용은 모른 채 객체의 사용법만 알고 사용한다는 뜻
  • 동시에 필요한 정보는 숨겨야 함
  • 캡슐화와 정보은닉으로 표현은 다르게 하지만 둘 다 코드의 내부 구현을 잘해서 외부에서 쉽게 사용하게 하고, 코드의 세부적인 내용은 모르게 한다는 측면에서 비슷한 의미로 사용됨
  • 캡슐화를 사용해야 하는 이유는 무엇일까?
    • 여러 가지가 있지만 일단 클래스를 설계할 때 클래스 간 간섭 및 정보 공유를 최소화하여 개별 클래스가 단독으로도 잘 동작할 수 있도록 해야 하기 때문
    • 각 클래스가 강하게 연결되어 있다면 독립적으로 사용하기 어려움
    • 또한.사 용자 입장에서는 상세한 내용을 모르더라도 인터페이스를 이해하면 클래스를 쉽게 사용할 수 있음
    • 파이썬에서는 이러한 개념을 가시성이라는 이름으로 적용 → 정보 은닉을 어떻게 할 것인가를 코드 레벨에서 조절
  • 실제 파이썬의 가시성 사용 방법에 대해 예시를 들어 설명
  • 먼저 코드를 작성해야 하는 상황은 다음과 같음

→ [코드 10—8]에서는 Inventory 객체에 add_new_item() 함수를 사용하여 새롭게 생성된 Product 객체를 넣어줌

  • 여기서 자료형을 비교하여 해당 객체가 Product 객체인지 확인 하고, 그렇지 않을 경우 ValueError가 발생
  • items는 Product 객체가 들어가는 공간 → get_number_of_items()를 사용하여 총 객체의 개수를 반환
  • 여기서 핵심은___items 변수
    • Inventory를 저장하는 공간 → add_new_item()을 통해 Product 객체를 넣을 수 있음
  • 하지만 다른 프로그램이 add_new_item()이 아니라 직 접 해당 객체에 접근해 새로운 값을 추가하려고 한다면 어떻게 할까?
    • #20
      • 다른 코드에서는 잘 실행되다가 20행의 my_inventory._items에서 오류가 발생
      • 왜냐하면 __가 함수 역할을 하는 예약 문자로 클래스에서 변수에 두 개가 붙어있어 사용될 클래스 내부에서만 접근할 수 있고, 외부에는 호출하여 사용하지 못하기 때문
      • ⇒ 즉, 클래스 내부용으로만 변수를 사용하고 싶다면 변수명’ 형태로 변수를 선언
      • 이러한 특징을 자바에 서는 private variable이라고도 함
      • 즉, 가시성을 클래스 내로 한정하면서 값이 다르게 들 어가는것을 막을 수 있다. 이를 정보은닉이라고함
  • 그렇다면 이러한 정보를 클래스 외부에서 사용하기 위해서는 어떻게 해야 할까?
    • 데코레이터 decorator라고 불리는 ©property를 사용
    • 클래스의 각 메서드 상단에 삽입 하여 해당 메서드의 기능을 추가하는 파이썬 문법
    • [코드 10-8]의 14행 뒷부분에 [코드 10-이를 추가하여 ©property를 사용하면 해당 변수를 외부에서 사용 가능

  • 다른 코드는 그대로 유지하고 마지막에 items라는 이름으로 메서드를 만들면서 ©property 를 메서드 상단에 입력
  • 그리고 외부에서 사용할 변수인 __items를 반환
  • 이렇게 코드를 추가하면 다음과 같이 외부에서도 해당 메서드를 사용가능

  • 이번 코드에서는 오류가 발생하지 않음
    • 여기서 주목할 부분은 __items 변수의 원래 이름이 아닌 items로 호출한다는 것
    • 바로 ©property를 붙인 함수 이름으로 실제 __items를 사용할 수 있는 것
    • 이는 기존 private 변수를 누구나 사용할 수 있는 public 변수로 바꾸는 방법 중 하나