[Python] Class - Abstract Class
Abstract Class (추상클래스)
-
추상클래스가 되면 인스턴스(객체)를 생성할 수 없다.
-
다른 클래스에게 상속만 가능해진다.
-
@abstractmethod
를 통해 자식클래스가 필수로 오버라이딩(Overriding) 해야하는 메서드를 지정한다. (적어도 한개는 필수로 지정해야한다.)
Example
class Animal:
def __init__(self):
print("I'm an animal")
def move(self):
print("I can move")
def eat(self):
print("I can eat")
class Human(Animal):
def __init__(self):
print("I'm a human")
def tool(self):
print("I can use tools")
class Bird(Animal):
def __init__(self):
print("I'm a bird")
def fly(self):
print("I can fly")
위의 예시코드를 보면, Human 과 Bird 클래스는 Animal 의 일종이기 때문에 (IS-A 관계) Animal 클래스를 상속받고있음을 알 수 있다.
그리고 Human 과 Bird 는 인스턴스를 생성해도 상대적으로 구체적인 모습이 떠오른다.
Human 의 인스턴스를 만들면 어떤 한 사람이라는 객체가 생기는 것이고,
Bird 의 객체를 만들면 어떤 새라는 객체가 생기는 것이다.
그런데 Animal 은 구체화된 형태가 없는 추상적인 큰 의미이다.
객체를 만들기에는 형태가 매우 추상적이다.
이러한 형태의 클래스를 실제로 객체를 만들지 못하게 선언하는 것이 클래스의 추상화이다.
추상화된 클래스는 다른 클래스에 상속시키는 용도로 주로 사용되며,
자식클래스에게 구현해야할 필수 메서드를 지정할 수 있다.
How to Make Abstract Class
Step1
abc 모듈을 import 한다.
from abc import *
abc 는 Abstract Base Class 의 약자이다.
Step2
추상화 시킬 클래스의 ()
안에 metaclass=ABCMeta
를 입력
class Animal(metaclass=ABCMeta):
def __init__(self):
print("I'm an animal")
def move(self):
print("I can move")
def eat(self):
print("I can eat")
def additional(self):
pass
Step3
자식클래스에서 구현해야할 메서드에 @abstractmethod 를 적용
-
추상클래스에서 어떤 메서드에도
@abstractmethod
를 적용하지 않을 경우, 해당 클래스는 추상화되지 않는다. 따라서, 적어도 한개는@abstractmethod
를 적용해야한다. -
@abstractmethod
가 적용된 메서드는 자식클래스가 필수로 오버라이딩 해야한다. 그렇게 하지 않으면, 자식클래스도 추상화되어버린다.
class Animal(metaclass=ABCMeta):
@abstractmethod # 해당 메서드는 자식클래스가 필수로 오버라이딩 해야한다.
def __init__(self):
print("I'm an animal")
def move(self):
print("I can move")
def eat(self):
print("I can eat")
@abstractmethod # 해당 메서드는 자식클래스가 필수로 오버라이딩 해야한다.
def additional(self):
pass
Completed Form
from abc import *
class Animal(metaclass=ABCMeta):
@abstractmethod # 해당 메서드는 자식클래스가 필수로 오버라이딩 해야한다.
def __init__(self):
print("I'm an animal")
def move(self):
print("I can move")
def eat(self):
print("I can eat")
@abstractmethod # 해당 메서드는 자식클래스가 필수로 오버라이딩 해야한다.
def additional(self):
pass
Practice
from abc import *
class Animal(metaclass=ABCMeta):
@abstractmethod
def __init__(self):
print("I'm an animal")
def move(self):
print("I can move")
def eat(self):
print("I can eat")
@abstractmethod
def additional(self):
pass
class Human(Animal):
def __init__(self):
print("I'm a human")
def tool(self):
print("I can use tools")
class Bird(Animal):
def __init__(self):
print("I'm a bird")
def fly(self):
print("I can fly")
def eat(self):
print("I eat something")
이제 Animal 의 인스턴스가 만들어지는지 확인해보자.
new_obj = Animal()
>>> TypeError
Animal 은 추상클래스가 되었기 때문에 인스턴스가 만들어지지않는다.
문제없이 추상화 시켰음을 알 수 있다. 이제 Human 의 인스턴스를 만들어보자.
new_obj = Human()
>>> TypeError
추상클래스가 아닌 Human 또한 인스턴스를 만들 수가 없다.
그 이유는 Human 클래스에 additional 메서드가 정의되지 않았기 때문이다.
Animal 클래스에서 @abstractmethod
로 지정한 메서드 두가지이다.
-
__init__
-
additional
이 두가지 메서드는 Animal 클래스를 상속받은 자식클래스(파생클래스)는 필수적으로 구현해야만 한다.
따라서 Human 클래스와 Bird 클래스에 additional 메서드를 추가적으로 구현해주면 문제가 해결된다.
추상메서드로 지정된(@abstractmethod
) 메서드를 오버라이딩 하지 않으면, 상속받은 자식클래스도 추상클래스가 되어버린다. 그래서 인스턴스가 생성되지 않은 것이다.
지정된 추상메서드는 오버라이딩 해야함을 잊어서는 안된다.
from abc import *
class Animal(metaclass=ABCMeta):
@abstractmethod
def __init__(self): # 해당 메서드는 자식클래스가 필수로 오버라이딩 해야한다.
print("I'm an animal")
def move(self):
print("I can move")
def eat(self):
print("I can eat")
@abstractmethod
def additional(self): # 해당 메서드는 자식클래스가 필수로 오버라이딩 해야한다.
pass
class Human(Animal):
def __init__(self): # 필수
print("I'm a human")
def tool(self):
print("I can use tools")
def additional(self): # 필수
print("Problem is solved")
class Bird(Animal):
def __init__(self): # 필수
print("I'm a bird")
def fly(self):
print("I can fly")
def eat(self):
print("I eat something")
def additional(self): # 필수
print("Problem is solved")
@abstractmethod
로 지정된 메서드를 자식클래스에서도 모두 구현하였다.
이제 인스턴스 생성에 문제없는지 확인해보자.
new_obj = Human()
>>> 'I'm a human'
문제없이 생성되었다. Human 의 메서드와 상속받은 메서드가 잘 동작하는지 확인해보겠다.
new_obj.move()
>>> 'I can move'
new_obj.tool()
>>> 'I can use tools'
new_obj.additional()
>>> 'Problem is solved'
문제없이 작동함을 확인할 수 있다.
Leave a comment