Python

Python_07_OOP

5_ssssseung 2021. 4. 13. 11:08

OOP

OOP

  • 객체(Object)
  • 객체지향프로그래밍(Object Oriented Programming)
  • 클래스(Class)와 객체(Object)

 

1. 객체

Python에서 모든 것은 객체(object)이다. 모든 객체는 타입(type), 속성(attribute), 조작법(method)을 가진다.

typeinstance
int0, 1, 2
str'', 'hello', '123'
list[], ['a', 'b']
dict{}, {'key': 'value'}
  • 타입 : 공통된 속성(attribute)과 조작법(method)을 가진 객체들의 분류
  • 인스턴스 : 특정 타입(type)의 실제 데이터 예시(instance)이다.

 

typeattributesmethods
complex.real, .imag 
str_.capitalize(), .join(), .split()
list_.append(), .reverse(), .sort()
dict_.keys(), .values(), .items()
# 객체.속성 형식으로 사용
complex_number.real 

# 객체.매서드 형식으로 사용
complex_number.imagmy_list.sort() 

 

1.1 매서드

  • 특정 객체에 적용할 수 있는 행위(behavior)를 뜻 한다.
  • dir() 로 해당 타입의 객체들의 매서드 확인 가능

 

2. 객체 지향 프로그래밍(Object-Oriented Programming)

  • Object가 중심(oriented)이 되는 프로그래밍

  • 객체지향의 장점

    • 코드의 직관성
    • 활용의 용이성
    • 변경의 유연성

 

3. 클래스(Class)와 객체(Object)

  • type: 공통 속성을 가진 객체들의 분류(class)
  • class: 객체들의 분류(class)를 정의할 때 쓰이는 키워드

 

3.1 클래스(Class) 생성

  • 클래스 생성은 class 키워드와 정의하고자 하는 <클래스의 이름>으로 가능하다.
  • <클래스의 이름>PascalCase로 정의한다.
  • 클래스 내부에는 데이터와 함수를 정의할 수 있고, 이때 데이터는 속성(attribute) 정의된 함수는 메서드(method)로 불린다.

 

class Person:    
	# _ underscore    
	def __init__(self, name): # 속성에 대한 정보를 저장        
		self.name = name        
	def talk(self):        
		return f'안녕, 나는 {self.name}' 
       
john = Person('john')john.talk()
  • self : 인스턴스 자신

    • Python에서 인스턴스 메서드는 호출 시 첫번째 인자로 인스턴스 자신이 전달되게 설계되었다.
    • 보통 매개변수명으로 self를 첫번째 인자로 설정 (다른 이름도 가능하지만 추천하지는 않는다.)

 

  • 생성자와 소멸자

    • 생성자 : 인스턴스 생성시 호출되는 함수 def __init__(self):
    • 소멸자 : 인스턴스가 소멸되기 직전에 호출되는 함수 def __del__(self):

 

  • 속성 정의

    class Person:    
    	def __init__(self, name):        
    		self.name = name    
    	def talk(self):        
    		print(f'안녕, 나는 {self.name}')
    
    # 속성에 접근하여 클래스 밖에서도 직접 변경 가능junsung.talk()
    junsung = Person('junsung')
    junsung.talk()junsung.name = '준성' 
    
  • 매직메서드

    # 특정 객체를 출력(print()) 할 때 보여줄 내용을 정의할 수 있음
    ['__new__', '__reduce__', '__reduce_ex__', 
     '__repr__', '__rmod__', '__rmul__', 
     '__setattr__', '__sizeof__', '__str__']
    
    class Person:    
    	def __str__(self):        
    	return '객체 출력(print)시 보여줄 내용'
    

 

4. 인스턴스 & 클래스 변수

4.1 인스턴스 변수

  • 인스턴스의 속성(attribute)
  • 각 인스턴스들의 고유한 변수
  • 메서드 정의에서 self.변수명로 정의
  • 인스턴스가 생성된 이후 인스턴스.변수명로 접근 및 할당
class Person:    
	def __init__(self, name):    
		#인스턴스 매서드중에 특별한 생성자 매서드..        
		self.name = name   

       
park = Person('park')
lee = Person('lee')
print(park.name)
print(lee.name)

 

4.2 클래스 변수

  • 클래스의 속성(attribute)
  • 모든 인스턴스가 공유
  • 클래스 선언 내부에서 정의
  • 클래스.변수명으로 접근 및 할당
# 클래스 내에 변수 지정 가능 => 클래스 변수 
class Person:    
	species = '사람' 
   
# 클래스에 넣어놓은 변수는 바뀌지 않음
Person.speciesiu = Person()
iu.speciesiu.species = '신'
iu.speciesPerson.species 

 

4.3 인스턴스 & 클래스간의 이름공간

  • 클래스를 정의하면, 클래스가 생성됨과 동시에 이름 공간(namespace)이 생성된다.
  • 인스턴스를 만들게 되면, 인스턴스 객체가 생성되고 해당되는 이름 공간이 생성된다.
  • 인스턴스의 어트리뷰트가 변경되면, 변경된 데이터를 인스턴스 객체 이름 공간에 저장한다.
  • 즉, 인스턴스에서 특정한 어트리뷰트에 접근하게 되면 인스턴스 => 클래스 순으로 탐색을 한다.

 

5. 메서드의 종류

5.1 인스턴스 메서드(instance method)

  • 인스턴스가 사용할 메서드
  • 클래스 내부에 정의되는 메서드의 기본값은 인스턴스 메서드
  • 호출시, 첫번째 인자로 인스턴스 자기자신 self이 전달됨
class MyClass:    
	def instance_method(self, arg1, arg2, ...):       
		 ...

 

5.2 클래스 메서드(class method)

  • 클래스가 사용할 메서드
  • @classmethod 데코레이터를 사용하여 정의
  • 호출시, 첫 번째 인자로 클래스 cls가 전달됨
class MyClass:    
@classmethod    
	def class_method(cls, arg1, arg2, ...):

 

5.3 스태틱 메서드(static method)

  • 클래스가 사용할 메서드
  • @staticmethod 데코레이터를 사용하여 정의
  • 호출시, 어떠한 인자도 전달되지 않음
class MyClass:    
	@staticmethod    
	def static_method(arg1, arg2, ...):

 

5.4 비교정리

  • 인스턴스는 3가지 메서드 모두에 접근 가능
  • 하지만 인스턴스에서 클래스 메서드와 스태틱 메서드는 호출하지 않아야 한다. (가능하다 != 사용한다)
  • 인스턴스가 할 행동은 모두 인스턴스 메서드로 한정 지어서 설계한다.

 

  • 클래스 또한 3가지 메서드 모두에 접근할 수 있다.

  • 하지만 클래스에서 인스턴스 메서드는 호출하지 않는다. (가능하다 != 사용한다)

  • 클래스가 할 행동은 다음 원칙에 따라 설계한다. (클래스 메서드와 정적 메서드)

    • 클래스 자체(cls)와 그 속성에 접근할 필요가 있다면 클래스 메서드로 정의한다.

    • 클래스와 클래스 속성에 접근할 필요가 없다면 정적 메서드로 정의한다.

      • 정적 메서드는 cls, self와 같이 묵시적인 첫번째 인자를 받지 않기 때문

 

6. 상속

6.1 상속

  • 클래스에서 가장 큰 특징은 상속이 가능하다는 것이다.
  • 부모 클래스의 모든 속성이 자식 클래스에게 상속 되므로 코드 재사용성이 높아진다.
class Person:    
	population = 0        
	def __init__(self, name='사람'):        
		self.name = name        
		Person.population += 1   
         
	def talk(self):        
		print(f'반갑습니다. {self.name}입니다.')       
                 
class Student(Person):    
	def __init__(self, name, student_id): 
		# 초기값은 부모클래스의 초기값을 덮어쓰워짐        
		self.name = name        
		self.student_id = student_id   

 

  • 상속 검사
# 전자가 후자의 서브클래스인가? True
issubclass(Student, Person) 

# 인스턴스인가? True
isinstance(s1, Student) 

# 인스턴스인가? True
isinstance(s1, Person)  

# 타입이 같은가? False (타입에 대해서 상속은 이뤄지지 않음)
type(s1) is Person  

#bool은 int의 자식클래스이기에 인스턴스 여부는 True
isinstance(True, int) 

# 타입은 같이 않으므로 False
type(True) is int   

# 서브클래스는 True
issubclass(bool, int)   

# 이 메서드로 해당 클래스의 상속관계 확인 가능
bool.mro()  

 

6.2 super()

  • 자식 클래스에 메서드를 추가로 구현할 수 있다.
  • 부모 클래스의 내용을 사용하고자 할 때, super()를 사용할 수 있다.
class Person:    
	population = 0        
	def __init__(self, name):        
		self.name = name        
		Person.population += 1      
      
	def talk(self):        
		print(f'반갑습니다. {self.name}입니다.')     
    
class Student(Person):    
	def __init__(self, name, student_id):         
		super().__init__(name) # 부모 클래스의 내용을 그대로 상속       
		self.student_id = student_id # 추가적으로 필요한 내용만 작성

 

6.3 다중상속

class Person:        
	def __init__(self, name):        
		self.name = name    
        
	def talk(self):        
		print('사람입니다')  
              
class Mom(Person):    
	gene = 'XX'   
     
	def swim(self):        
		print('첨벙첨범')
                
class Dad(Person):    
	gene = 'XY'     
   
	def walk(self):        
		print('씩씩하게 걷기')  

# 부모클래스에서 동일한 클래스변수가 있을때는 먼저 상속한 클래스에서 가져옴
class FirstChild(Mom, Dad):    
	def __init__(self):   
                 
	def cry(self):        
		print('응애')   
         
	def walk(self):       
		print('아장아장')        

 

7. 메서드 오버라이딩

Method Overriding(메서드 재정의): 자식 클래스에서 부모 클래스의 메서드를 재정의하는 것

  • 상속 받은 메서드를 재정의할 수도 있다.
  • 상속 받은 클래스에서 같은 이름의 메서드로 덮어쓴다.
class Person:    
	def __init__(self, name, age, number, email):        
		self.name = name        
		self.age = age        
		self.number = number        
		self.email = email             

def talk(self):        
	print(f'안녕, {self.name}')        

class Soldier(Person):    
	def __init__(self, name, age, number, email, level):        
		super().__init__(name, age, number, email)        
		self.level = level            

def talk(self):=    
	# 동일한 이름의 메서드를 자식클래스에서도 선언하는 경우 덮어씀        
	if self.level == '참모총장':            
		print('내 밑으로 집합')        
	else:            
		print(f'충성 충성 {self.level}, {self.name}입니다 ^^7')

'Python' 카테고리의 다른 글

Python_06_모듈&패키지  (0) 2021.04.09
Python_05_데이터_구조  (0) 2021.04.07
Python_04_예외처리  (0) 2021.04.06
Python_03_함수  (0) 2021.04.05
Python_02_제어문  (0) 2021.04.04