Python

객체지향 프로그래밍 2

김디니 2022. 7. 20. 16:57

객체는 속성메서드(기능을 담당)가 존재하는 모습이다.

    이 모습을 클래스로 정의하고, 실질적으로 사용하는 것은 개별 인스턴스이다.

함수는 input이 들어오면 output을 리턴한다.

class Person:
    pass

p1 = Person() # 인스턴스 생성 
p1.name = '홍길동' # 인스턴스 속성

print(p1.name) 
#출력 홍길동
class Person:

    def greeting(self): # 인스턴스 메서드 (인스턴스가 활용할 메서드이다.)
        print('안녕하세요~!')

iu = Person() # ()는 메서드를 호출한다. 
iu.greeting() # 인스턴스가 메서드를 실행시키고 있다.  
class Person:
    species = '사람' #클래스 변수

print(Person.species) # 클래스 변수(속성)

 

self

인스턴스를 만들 때는 이름 정보를 받아서 하고자 한다.

class Person:
    def __init__(self, name): # 인풋 2개를 받아서 함수 내에서 쓰겠다는 선언

        # 개별 인스턴스에 각각 name 속성을 지정하고자 한다. 
        self.name = name

# 인스턴스 만들 때
jimin = Person('지민')
print(jimin.name) 

#출력 지민

 

Q. Input 2개(self, name)를 넣어 활용하기로 했으면서,

jimin = Person('지민')에서 1개 ('지민')만 넣는 이유는?

A. 내부적으로 모든 인스턴스 메서드 중 (def init (self, name):) 첫 번째로 self를 넘겨준다는 약속이 되어있다.

즉, 내부적으로 호출될 때에는 다른 모습이 숨겨져 있다.

 

def greeting(self):
    print('안녕하세요, 지민입니다.')

jimin = Person('지민')
jimin.greeting()

iu = Person('지은')
iu.greeting()
# 출력 안녕하세요, 지민입니다.
# 안녕하세요, 지민입니다.
def greeting(self):
    print('안녕하세요, {self.name}입니다.')

jimin = Person('지민')
jimin.greeting()

iu = Person('지은')
iu.greeting()
# 출력 안녕하세요, 지민입니다.
# 안녕하세요, 지은입니다.

jmin.greeting()은 내부적으로 Person.greeting(jimin) (이런 느낌으)로 항상 넘겨준다.

self는 호출하는 인스턴스를 파이썬 내부적으로 전달해준다.

즉, jimin = Person('지민')에서 1개의 값 ('지민')만 넣어줘도 내부적으로 self의 값도 들어가기 때문에 2개의 인풋이 들어오는 것으로 인식하는 것이다.

 

랜덤한 로또 번호를 출력하는 코드를 작성해보자.

import random

for i in range (5)
    numbers = range(1, 46)
    result = random.sample(numbers, 6)
    result.sort()
    print(result)

이 코드를 바탕으로 클래스와 함수를 만들었다고 가정해보자.

# 함수.ver
import lotto_function

buy_numbers = lotto_function.generate_lotto(5)
lotto_function.check(buy_number, [1, 2, 3, 4, 5, 6])

함수는 input을 넣으면 output을 주는 것 뿐이다. 이외의 행위를 할 수 없다.

# 클래스.ver
import lotto_clss

lotto = lotto_class.Lotto() # lotto는 인스턴스
lotto.generate_lotto() # 생성해 (verb)
print(lotto.numbers)    # 숫자 출력해
print(lotto.get_money([1, 2, 3, 4, 5, 6])) # 당첨 확인해

lotto 인스턴스로 속성(numbers)을 볼 수 있고, 생성하고 확인(get_money)할 수 있다. (다양한 행위가 가능하다)

 

다시 말해, 클래스를 정의한다는 것은 하나의 타입이 속성(데이터)을 가지고 있고, 어떠한 메서드(행위)를 할 수 있다는 것이다. 

이 점에서 함수와는 다르게 클래스는 객체를 조작할 수 있는 형태를 가지고 있다. 

 

클래스

클래스 속성(attribute)

  • 클래스 역시 변수를 가지고 있다.

    (인스턴스와는 다르다.)

 

인스턴스 - 클래스의 이름 공간

  • 클래스를 정의하면 클래스와 해당하는 이름 공간이 생성된다.
  • 인스턴스를 만들면 인스턴스 객체가 생성되고 이름 공간이 생성된다.
  • 인스턴스에서 특정 속성에 접근하면 인스턴스 - 클래스 순으로 탐색한다.

글로벌 영역, 로컬 영영(함수 내부), 빌트인 등의 공간과 순서와 같은 원리이다.

인스턴스 이름 공간에 값이 없다면 클래스의 이름 공간에서 탐색한다.

 

클래스 메서드

  • 클래스가 사용할 메서드이다.
  • @classmethod : 데코레이터(@)를 사용하여 정의한다.
    • 데코레이터: 함수를 어떤 함수로 꾸며 새로운 기능을 부여하는 것이다.
  • 호출 시 첫 번째 인자로 클래스(cls)가 전달된다.
    • 인스턴스 메서드는 첫 번째 인자로 self가 전달된다.
    • cls, self 모두 관용적으로 이름을 붙여줬을 뿐, 예약어가 아니다.
class MyClss

    @classmethod
    def class_method(cls, arg1, ...)

!!일반적으로 클래스 메소드에서는 인스턴스 변수와의 상호작용은 없다.!!

 

스태틱 메소드

  • 인스턴스 변수, 클래스 변수를 전혀 다루지 않는 메서드이다.
  • 기능을 위해 사용된다.

 

각 메서드 사용 정리

1. 인스턴스 메서드

  • 인스턴스가 호출하면서 메서드 내부에 인스턴스 자체가 필요할 때 사용한다.

2. 클래스 메서드

  • 클래스가 호출할 예정일 때 메서드 내부에서 클래스 자체가 필요할 때 사용한다.

3. 스태틱 메서드

  • 내부적으로 클래스, 인스턴스 모두 필요 없을 때 사용한다.
  • 즉, 스태틱 메서드 안에서 클래스나 인스턴스는 사용할 수 없다.

 

객체 지향의 핵심 개념

객체지향의 핵심 4가지

  • 추상화: 동작할 수 있는 메서드를 정의한다.
  • 상속
  • 다형성
  • 캡슐화

기능, 정보, 조작을 표현한다.

상속

클래스 간의 부모-자식 관계를 정립한다.

상속 관련 함수와 메서드

  • isinstance(object, classinfo)
  • issubclass
  • super()
    • 자식클래스에서 부모클래스를 사용하고 싶은 경우에 사용한다.

상속 정리

  • 파이썬의 모든 클래스는 object로부터 상속된다.
  • 부모 클래스의 모든 요소가 상속된다.
  • **super()**를 통해 부모 클래스의 요소를 호출할 수 있다.
  • 메소드 오버라이딩을 통해 자식 클래스에서 정의가 가능하다.

다중 상속

  • 두개 이상의 클래스를 상속받는 경우
  • 상속받은 모든 클래스의 요소

 

다형성 (Polymorphism)

  • 여러 모양을 뜻한다.
  • 동일한 메서드가 클래스에 따라 다르게 행동할 수 있음을 의미한다.

메서드 오버라이딩

  • 상속받은 메서드를 재정의 한다.

    즉, 메서드를 덮어쓰기 할 수 있다.

캡슐화

실제로 파이썬은 수단과 방법을 써서 접근이 가능하다.

접근제어자 종류

  • Public Access Modifier: 어디서나 호출이 가능하다.
  • Protexted Access Modifier: 부모/자식에서만 접근 가능하다.
  • Private Access Modifier: 본인만 접근 가능하다. (클래스 그 자체이다)