본문 바로가기
Python/Basic

[파이썬, Python] 객체지향 프로그래밍 - 객체 지향과 클래스(Class)

by coding-choonsik 2023. 3. 9.
728x90
반응형
SMALL

1. 객체지향 프로그래밍

  • 문제를 여러개의 객체 단위로 나눠 작업하는 방식
  • 특징
    • Abstraction(추상화) : 만들고자 하는 것들의 공통적인 것을 바탕으로 하나로 묶는 것
    • Encapsulation(캡슐화): 맡은 역할의 수행을 위해 최소한의 외부 접근만을 허용하는 것
    • Polymorphism(다형성): 자료형에 구애 받지 않고 프로그래밍 하는 것
    • Inheritance(상속): 하위 개념이 상위 개념의 속성 및 동작 등을 물려받는 것

 

1-1. 객체(Object)란?

  • 물리적으로 존재하거나 추상적으로 생각할 수 있는 것 중에서 자신의 속성을 가지고 있고 다른 것과 식별 가능한 것을 말함
  • 하나의 클래스로부터 여러 개의 객체(object)가 생성될 수는 있지만 각각은 서로 유일(unique)
  • 서로 다른 객체는 특별히 선언한 문장이 없으면 서로  독립적

 

1-2.  절차지향 프로그래밍(Procedural Programming)

  • 개체를 순차적으로 처리하여 프로그램 전체가 유기적으로 연결
  • 대표적인 프로그래밍 언어: c언어 등
  • 장점: 한번에 실행되기 때문에 실행속도가 빠름
  • 단점
    • 문제를 해결하기 위하여 전체를 수정해야하기 때문에 디버깅이 어려움
    • 실행순서가 정해져 있기 때문에 코드의 순서가 바뀌면 결과가 달라질 가능성이 높음

 

1-3. 객체지향 프로그래밍

  • 프로그램을 다수의 객체로 만들고, 이들끼리 서로 상호작용하도록 만드는 프로그래밍 언어
  • 클래스 내 프로퍼티에 직접 값을 변경하기보다는 메소드를 통해 프로퍼티의 값을 변경하는 것이 좋음
  • 대표적인 프로그래밍 언어:  파이썬, 자바, c++ 등
  • 장점
    • 상속이 가능하기 때문에 코드를 재사용할 수 있음
    • 독립적인 객체로 이루어져있기 때문에 디버깅 작용이 유리
  • 단점
    • 객체의 역할과 기능이 다양하여 프로그래밍에 많은 시간이 소요됨
    • 처리속도가 절차지향언어보다 느림

2. 클래스(Class)

2-1. 클래스란❓

  • 객체를 생성하기 위한 일종의 설계도와 같음
  • 클래스는 프로퍼티(필드), 메소드(함수)로 구성되어 있음
    • 프로퍼티(Property): 데이터가 저장되는 곳(변수)
    • 메소드(method): 객체의 동작에 해당하는 실행 블록

2-2. 클래스와 객체

  • 건축 설계도가 클래스라면, 실제로 지어진 집은 객체
  • 객체는 클래스로 생성되어 구체화된 인스턴스
  • 실제로 클래스가 인스턴스화 되어 메모리에 상주하는 형태를 객체라고 부름
  • 파이썬의 모든 변수와 함수는 객체로 저장

2-3. 클래스의 생성

  • 클래스를 통해 호출되는 변수를 프로퍼티 또는 필드라고 부름
  • 클래스를 통해 호출되는 함수를 메소드라고 부름
  • 클래스명은 관례적으로 대문자로 시작
  • ✅ 메소드 생성시 self 키워드를 반드시 생성
    • 관례적으로 self라고 함 
    • 클래스의 호출한 각 객체를 알려줌
class 클래스명:
  프로퍼티명1 = 값1
  프로퍼티명2 = 값2
  ...

  def 메소드명1(self,변수1, 변수2,..):
    메소드가 호출되면 실행할 문장
    ...

  def 메소드명2(self,변수3, 변수4,..):
    메소드가 호출되면 실행할 문장
    ...

 

  • 클래스를 통해 객체를 생성해보자.
# Dog이라는 클래스 생성
class Dog:  
  name = '루시'     # 클래스 내 프로퍼티
  age = 13
  family = '포메'


  def eat(self):    # 재활용하기 위해 메소드 객체의 메모리를 따로 저장
    print(self)
    print('사료를 먹습니다')

# Dog클래스 통해 Rucy라는 객체 생성
Rucy = Dog()

print(Rucy.name)
>>> 루시
print(Rucy.age)
>>> 13
print(Rucy.family)
>>> 포메
Rucy.eat()
>>> 사료를 먹습니다
print(id(Rucy))     # Rucy 객체의 주소값
>>> 139798572281328

3. 생성자(Constructor)

  • 클래스를 객체화 시킬 때 가장 먼저 자동으로 실행되는 메소드
  • __init__
  • 생성자에서는 해당 클래스가 다루는 데이터를 정의하고 초기화 함

 

3-1. 생성자 메소드 만들기

class Dog:
  def __init__(self):
    print(self, 'init가 호출됨!')
    

# 객체가 생성되면서 생성자가 자동으로 호출됐기 때문에 메소드가 실행됨
Rucy = Dog() 

# Dog 클래스를 통해 Rucy 객체가 생성됨
>>> <__main__.Dog object at 0x7f346818e8e0> init가 호출됨!

class Dog:
  def __init__(self):
    self.name = '이름없음'        # 객체가 생성되면 자동으로 실행됨
    self.age = 0


Rucy = Dog()
print(Rucy)
>>> <__main__.Dog object at 0x7f346818e970>

print(Rucy.name)
>>> 이름없음

print(Rucy.age)
>>> 0

Ppomi = Dog()
print(Ppomi)
>>> <__main__.Dog object at 0x7f346819b340>

print(Ppomi.name)
>>> 이름없음

print(Ppomi.age)
>>> 0
  • Rucy객체와 Ppomi 객체의 name, age프로퍼티를 설정
Rucy.name = 'Rucy'
Rucy.age = 13
Ppomi.name = 'Ppomi'
Ppomi.age = 7

print(Rucy)
print(Rucy.name)
print(Rucy.age)
>>> 
<__main__.Dog object at 0x7f346818e970>
Rucy
13

print(Ppomi)
print(Ppomi.name)
print(Ppomi.age)
>>> 
<__main__.Dog object at 0x7f346819b340>
Ppomi
7

3-2. 생성자 메소드에 self를 쓰는 이유 🤔

class Dog:
  def __init__(self):
    name = '이름없음'
    age = 0
    
Rucy = Dog()
print(Rucy)
>>> <__main__.Dog object at 0x7f34681a42b0>
print(Rucy.name)
>>> AttributeError: 'Dog' object has no attribute 'name'
  • 생성자 메소드에 self를 붙이지 않으면 어떤 객체에 메소드를 적용시킬지 알 수 없음.
class Dog:
  def __init__(self):
    self.name = '이름없음'
    self.age = 0
    self.nickname = '닉네임없음'

  def go(self):
    print(f'{self.nickname}이 달립니다!')
Rucy = Dog()   # 객체 생성
Rucy.name = 'Rucy'
Rucy.go()

>>> 닉네임없음이 달립니다!   # 생성자 메소드에서 self.nickname을 '닉네임없음'으로 설정

Ppomi = Dog()
Ppomi.name = 'Ppomi'
Ppomi.go()

>>> 닉네임없음이 달립니다!

  • Rucy() 객체의 nickname을 설정하여 go()메소드 실행
class Dog:
  def __init__(self):
    self.name = '이름없음'
    self.age = 0
    self.nickname = '닉네임없음'
  
  def go(self, nickname):
    print(f'{nickname}이 달립니다!')
    
Rucy = Dog()
Rucy.name = 'Rucy'
Rucy.go('강아쥐')

>>> 강아쥐이 달립니다!

class Dog:
  def __init__(self, name, age, nickname='닉네임없음')   # nickname 매개변수는 '닉네임없음'이 기본값
    self.name = name
    self.age = age
    self.nickname = nickname
    
Rucy = Dog()   

# 매개변수를 입력하지 않으면 에러!
>>> TypeError: __init__() missing 2 required positional arguments: 'name' and 'age'

Rucy = Dog('Rucy', 13)
print(Rucy.name)
>>> Rucy
print(Rucy.age)
>>> 13
print(Rucy.nickname)  
>>> 닉네임없음           # 디폴트 매개변수

4. 메소드(Method)

  • 해당 클래스의 객체에서만 호출 가능한 함수
  • 해당 객체의 속성에 대한 연산을 행함
  • 객체이름.메소드명() 형태로 호출

 

4-1. 메소드 정의하기

  • 은행에서 번호대기표를 뽑아서 몇명의 대기인원이 있는지 알려주는 프로그램을 작성해보자.
class Counter:
  def __init__(self):
    self.num = 0    		# 0이라는 초기값으로 시작

  def increment(self):
    self.num += 1    		# num에 1씩 증가

  def decrement(self):
    self.num -= 1           # 하나씩 빠짐

  def current_value(self):  # 현재값을 보여줌
    return self.num
  
  def reset(self):
    self.num = 0
KBank = Counter()   # 객체 생성
print(KBank.num) 

>>> 0

KBank.increment()
print(KBank.num)

>>> 1

KBank.decrement()
print(KBank.num)

>>> 0

print(KBank.current_value())
>>> 0


KBank.increment()
KBank.increment()
KBank.increment()
KBank.increment()
KBank.increment()
print(f'현재 대기인원: {KBank.current_value()}')

>>> 현재 대기인원: 5
  • 다른 은행의 객체도 생성
HanaBank = Counter()   # 객체 생성
print(f'현재 대기인원: {HanaBank.current_value()}')

>>> 현재 대기인원: 0

HanaBank.increment()
HanaBank.increment()
HanaBank.increment()
HanaBank.increment()
print(f'현재 대기인원: {HanaBank.current_value()}')

>>> 현재 대기인원: 4

# 초기화하는 메소드 실행
HanaBank.reset()
print(f'현재 대기인원: {HanaBank.current_value()}')    

>>> 현재 대기인원: 0

4-2. 메소드 타입

  • 인스턴스 메소드(instance method): 객체 형태로 호출되기 때문에 해당 메소드를 호출한 객체에서만 사용
    • 프로퍼티(객체)와 관련이 있어서 사용
  • 클래스 메소드(class method): 클래스 이름으로 호출하는 메소드(객체생성x)
    • 메소드 선언 위에 @staticmethod라고 표기
    • self가 없음

  •  Math 클래스 에서 두 수를 더하는 메소드와 곱하는 인스턴스 메소드를 만들어보자.
class Math:
  def add(self, x, y):
    return x + y
  def multiply(self, x, y):
    return x * y
math = Math()   # 객체 생성

result1 = math.add(10,3)
print(result1)
>>> 13

result2 = math.multiply(10,3)
print(result2)
>>> 30

  •  Math 클래스 에서 두 수를 더하는 메소드와 곱하는 클래스 메소드를 만들어보자.

 

class Math:
  @staticmethod
  def add(x, y):      # self가 없음
    return x + y
  @staticmethod
  def multiply(x, y):
    return x * y
result3 = Math.add(10, 3)
print(result3)
>>> 13

result4 = Math.multiply(10, 3)
print(result4)
>>> 30

 

  • 클래스 메소드를 생성하는 클래스에서 인스턴스 함수를 만들어보자.
  • @staticmethod: 파이썬 지시어(@)이기 때문에 위에서부터 실행되어 입력하지 않은 부분에 자동으로 실행
class Math:
  @staticmethod    
  def add(x, y):
    return x + y
  @staticmethod
  def multiply(x, y):
    return x * y
 # 자동으로 @staticmethod를 넣어줌
 # 인스턴스 메소드로 만들어보기
  def div(self, x, y):  
    return x / y

 

result5 = Math.div(10, 3)
print(result5)
>>> 3.3333333333333335

math =Math()        # 인스턴스 메소드, 객체를 생성하여 사용
result6 = math.div(10, 3)
print(result6)
>>> 3.3333333333333335

 

 

728x90
반응형
LIST