TIL-no.20 Python 상속과 다형성, 날짜와 시간

sanghun Lee·2020년 7월 3일
0

Today I Learned

목록 보기
18/66

상속(Inheritance)

상속하는 클래스를 부모 클래스,
상속받는 클래스를 자식 클래스,
자식클래스가 부모클래스의 내용을 가져다 쓸 수 있는 것이다.

class Human():
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
    
    def wave(self):
    	print("손을 흔든다")
        
class Dog():

	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
    def wag(self):
    	print("꼬리를 흔든다")        

person = Human()
person.walk()
person.eat()
person.wave()

dog = Dog()
dog.walk()
dog.eat()
dog.wag()

#사람과 개는 서로 다른 클래스이나 겹치는 개념이 많음

아래에 중복되는 것을 피하기 위해 animal클래스를 새로 만들었다.
아래 human과 dog 클래스의 괄호안에 Animal을 넣어서 상속을 시켰다.
(상속시키는방법이 이렇다고한다.)
이렇게하면 부모(Animal)가 가지고 있는 메소드를 그대로 사용할 수 있다.

class Animal():
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
class Human(Animal):
   
    def wave(self):
    	print("손을 흔든다")
        
class Dog(Animal):
        
    def wag(self):
    	print("꼬리를 흔든다")        

person = Human()
person.walk()
person.eat()
person.wave()

dog = Dog()
dog.walk()
dog.eat()
dog.wag()

#이렇게해도 출력결과는 똑같다.
#person 과 dog는 자식클래스로서 Animal(부모)클래스에 있는 함수를 가져와서 사용한 것이다.

오버라이드(Override)

같은 이름을 가진 메소드를 덮어쓴다는 의미이다.

단순 오버라이드

동물에 인사함수를 더해보자

class Animal():
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
    def greet(self):
    	print("인사한다")
        
class Human(Animal):
   
    def wave(self):
    	print("손을 흔든다")
    def greet(self)
    	self.wave # wave method실행

class Dog(Animal):
        
    def wag(self):
    	print("꼬리를 흔든다")   
    
    def greet(self):
    	self.wag()

person = Human()
person.greet()

dog = Dog()
dog.greet()

이렇게하면 부모에게 상속받은 메소드에서 엎어쓰기 때문에 
손을흔든다
꼬리를흔든다
로 출력이 된다.

cow 라는 클래스를 추가해보자

class Animal():
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
    def greet(self):
    	print("인사한다")
        
class Human(Animal):
   
    def wave(self):
    	print("손을 흔든다")
    def greet(self)
    	self.wave # wave method실행
        
class Cow(Animal):
	'''소'''


class Dog(Animal):
        
    def wag(self):
    	print("꼬리를 흔든다")   
    
    def greet(self):
    	self.wag()

cow = Cow()
cow.greet()

#이렇게하면 Animal에 있는 인사한다가 출력된다.
#따로 지정하지 않았기 때문에 사람과 개는 부모의 greet method를 자식클래스에서 override하였고 
#Cow 클래스는 지정해주지 않았기때문에 부모클래스의 greet method를 그대로 사용하는 것이다.

아래 그림을 보고 이해해보자.

super()

자식클래스에서 부모클래스의 내용을 사용하고 싶은 경우 아래와 같이 작성하면 된다.
super().부모클래스내용

예제를 보자

class Animal( ):
    def __init__( self, name ):
        self.name = name

class Human( Animal ):
    def __init__( self, name, hand ):
        super().__init__( name ) # 부모클래스의 __init__ 메소드 호출
        self.hand = hand

person = Human( "사람", "오른손" )

부모클래스의 간단한 인사 함수만 가져오는 예제

class Animal():
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
    def greet(self):
    	print("인사한다")
        
class Human(Animal):
   
    def wave(self):
    	print("손을 흔들면서")
    def greet(self)
    	self.wave()
        super().greet()# 부모클래스의 인사한다를 가져오는 방법
        


person = Human()
person.greet()
#output
손을흔들면서
인사한다
라고 출력된다.

init 과 함께 사용해보자 (가장 많이 해당될 것임)[겁나어렵네]

class Animal():
	def __init__(self, name):
    	self.name = name
        
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
    def greet(self):
    	print("{}이/가 인사한다".format(self.name))
        
class Human(Animal):
	
   
    def wave(self):
    	print("손을 흔들면서")
        
    def greet(self)
    	self.wave()
        super().greet()# 부모클래스의 인사한다를 가져오는 방법
        


person = Human("사람")
person.greet()

#output
손을흔들면서
사람이/가 인사한다
로 나온다.
class Animal():
	def __init__(self, name):
    	self.name = name
        
	def walk(self):
    	print("걷는다")
    
    def eat(self):
    	print("먹는다")
        
    def greet(self):
    	print("{}이/가 인사한다".format(self.name))
        
class Human(Animal):
	def __init__(self, name, hand):
    	super().__init__(name)
        self.hand = hand
   
    def wave(self):
    	print("{}을 흔들면서".format(self.hand)) # 인스턴스의 hand를 가져와야하기에 self.hand
        
    def greet(self)
    	self.wave()
        super().greet()# 부모클래스의 인사한다를 가져오는 방법
        


person = Human("사람", "오른손") #사람과 오른손이 name 과 hand에 들어갈 것.
person.greet()

#output
오른손을 흔들면서 #오른손은 Human의 인스턴스를 만들며 넘겨줌 
사람이/가 인사한다
로 나온다.

내 예외 만들기

예외란 사용자가 직접 예외처리를 하면 코드의 직관성을 높일수 있다.
파일을 하나 만들어서 예외를 정의하거나
Exception클래스를 상속받아 만든다

value = '가'
try:
	if value not in ['가위','보','바위']:
    	raise ValueError("가위바위보 중에 하나의 값이어야 합니다.")
except ValueError:
	print("에러가 발생했습니다.")
    
#output - > 에러가 발생했습니다.

만약 많은량의 함수중 어느 곳에서 에러가 발생하였는지 찾는 것은 번거롭고 수고스러운 일일 것.
파이썬에서는 예외도 하나의 클래스이기 때문에 예외를 손쉽게 추가하거나 새로 만들 수 있다.

두개의 파일을 만들어 한번 사용해보자
1.my_exception.py

from UnexpectedRSPValue import UnexpectedRSPValue

value = '가'
try:
	if value not in ['가위','보','바위']:
    	raise UnexpectedRSPValue
except UnexpectedRSPValue:
	print("에러가 발생했습니다.")
    
#output - > 에러가 발생했습니다.

2.unexpectedRSPValue.py

class UnexpectedRSPValue(Exception):
	'''가위 바위 보 가운데 하나가 아닌값인 경우에 발생하는 에러'''

에러의 최상위 클래스는 Exception이고
필요하면 ValueError를 사용해도됨. 위에서는 최상위클래스 Exception 을 상속받아 사용했다.

이번에는 다른곳에서 발생하는 에러와 겹치지는 않을 것임.
이해를 위해 새로운 파일을 하나 더 만들어보자

3.may_exception.py
해당파일은 exception을 두가지 만들어 분기를하여 원하는 에러를 선택하여 사용할 수 있도록 만들었음.

class BadUserName(Exception):
	'''이름오류'''
class PasswordNotMatched(Exception):
	'''패스워드오류'''
def sign_up():
	'''회원가입 함수'''
try:
	sign_up()
except BadUserName:
	print("이름으로 사용할 수 없는 입력입니다.")
except PasswordNotMatched:
	print("입력한패스워드가 서로 일치하지 않습니다.")

profile
알고리즘 풀이를 담은 블로그입니다.

0개의 댓글