본문 바로가기

코딩/Python

[Python/파이썬] Class(클래스) 기초 정리 - 4 : 추상 클래스, 클래스 변수

반응형

※ 이 글을 쓰는 사람은 SW 비전공자입니다.

※ 개인 공부를 위해 정리하는 글이며, 작성한 코드들은 효율성, 깔끔함(?) 등과는 거리가 멀 수 있습니다.

 

2021.03.14 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 1 : 개념, 사용법

2021.03.20 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 2 : has-a 관계, 상속 개념

2021.03.21 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 3 : 다중상속, super().__init__(), 메서드 오버라이딩

2021.03.22 - [코딩/Python] - [Python/파이썬] Class(클래스) 기초 정리 - 4 : 추상 클래스, 클래스 변수

2021.03.27 - [코딩/Python] - [Python/파이썬] Class(클래스) 메서드 self 설명


  클래스 마지막 편이다. 추상 클래스와 클래스 변수라는 개념이 있어 정리해보았다. 이번 편에도 코딩 도장과 위키 독스의 '점프 투 파이썬'을 참고하여 정리한다. 참고 링크는 하단에 기재하였음.

 

1. 추상 클래스

  추상 클래스는 클래스 내부의 메서드들이 내용은 빼고 이름만 정의된 클래스라고 한다. 지금까지 예를 들었던 무기 클래스를 예시로 들어보면 무기는 attack()이라는 메서드를 가질 수 있지만, 내부 구현 내용은 총인지 검인지에 따라 내용이 달라질 수 있다는 것이다. 아래 그림과 같이 쉽게 도식화해보았다.

 

 

< 추상 클래스 개념 : 얼핏 보면 메서드 오버라이딩과 동일해보임 >

 

  추상 클래스에서 정의된 메서드를 추상 클래스를 상속받는 자식 클래스에서 세부 구현해야 한다. 이전 편에서 얘기했던 메서드 오버 라이딩이랑 비슷한 부분 같다. 그래서 한 가지 궁금해졌다. 보기에는 메서드 오버 라이딩과 다르지 않은데 왜 추상 클래스 개념을 사용해야 하는 거지?

 


※ 추상 클래스는 왜 쓰는가?

 

다른 티스토리에서 잘 정리해주셔서 참고하였다.(아래 링크 첨부)

  일단 메서드 오버 라이딩과 다른 점은 추상 클래스로 정의하면 추상 클래스를 상속받는 자식 클래스에서 정의된 추상 메서드에 대해 모두 재정의를 해야 한다는 점이다.

< 추상 클래스에서 정의 된 추상 메서드는 하위 클래스에서 모두 재정의되어야 한다.>

 

 

   추상 클래스는 프로그램 구조 설계 시 기획자가 추상 클래스로 꼭 구현이 필요한 메서드를 정의하고 이를 상속하게 하는 것이다. 개발자들이 메서드를 놓치거나 오류를 발생시키는 것을 방지하는 목적이 있다. 또한, 메서드의 구현 내용을 상속받는 클래스에 떠넘겨 책임을 위임하는 부분도 있다고 한다. 작은 규모의 프로젝트에서는 거의 안 쓴다고 하니 이런 개념도 있다는 것만 알아두면 좋을 것 같다.

  

  추상 클래스를 사용하는 이유는 아래 2개 링크를 참고하였다.

 

 

 

추상 메소드와 오버라이딩

추상 메소드 추상 클래스는 실체 클래스가 공통적으로 가져야 할 필드와 메소드들을 정의해 놓은 추상적인 클래스이므로 실체 클래스의 맴버(필드, 메소드)를 통일화하는데 목적이 있다. 모든

21413011.tistory.com

 

구름EDU - 모두를 위한 맞춤형 IT교육

구름EDU는 모두를 위한 맞춤형 IT교육 플랫폼입니다. 개인/학교/기업 및 기관 별 최적화된 IT교육 솔루션을 경험해보세요. 기초부터 실무 프로그래밍 교육, 전국 초중고/대학교 온라인 강의, 기업/

edu.goorm.io

 


  추상 클래스 사용하는 법은 아래와 같다. abc(=abstract base class) 모듈을 import 하고 추상 클래스를 정의할 때 괄호 안에

metaclass=ABCMeta를 입력해주면 된다. 추상 메서드를 정의하는 방법은 메서드명 위에 @abstractmethod를 쓰면 된다. 자세한 내용은 아래 코드 참고!!

 

#추상 클래스 사용을 위한 모듈 import
from abc import *

#Weapone 클래스 정의(추상 클래스)
class Weapone(metaclass=ABCMeta):
   @abstractmethod
   def '메서드명'(self):
       pass

 

  위 도식화 그림을 위해 간단히 테스트 코드를 짜보았다. 실제 추상 클래스를 상속받는 자식 클래스에서 메서드를 모두 재정의하지 않으면 오류가 걸리는지 확인.

 

#추상 클래스 사용을 위한 모듈 import
from abc import *

#Weapone 클래스 정의(추상 클래스)
class Weapone(metaclass=ABCMeta):
   @abstractmethod
   def attack(self):
       pass
    
   @abstractmethod 
   def guard(self):
       pass

#Sword 클래스 정의 : Weapone 클래스 상속 
class Sword(Weapone):
    #부모 클래스 attack 메서드 재정의, guard 메서드는 일부로 빼봄.
    def attack(self): 
        print("칼을 무엇이든지 벨 수 있다") 
        print("칼을 찌를 수도 있지")
        print("칼은 던지기도 돼!")

short_sword = Sword()
short_sword.attack() 

 

<결과>

 

    short_sword = Sword()
TypeError: Can't instantiate abstract class Sword with abstract methods guard

 

  TypeError 오류가 발생한다. 자세한 내용을 보니 추상 클래스의 guard 메서드를 인스턴스화 시킬 수 없다는 내용이다. 추상 클래스에서 정의된 모든 추상 메서드는 상속받는 자식 클래스에서 모두 재정의 되어야 한다. guard 메서드가 정의되지 않아서 오류가 발생한 것이다. 위 코드에서 Sword 클래스에 guard에 대한 메서드 내용을 추가해보았다.

 

class Sword(Weapone):
    def attack(self): #메서드 오버라이딩
        print("칼을 무엇이든지 벨 수 있다") 
        print("칼을 찌를 수도 있지")
        print("칼은 던지기도 돼!")
    
    def guard(self):
        print("칼로 방어하기")

 

<결과>

 

칼을 무엇이든지 벨 수 있다
칼을 찌를 수도 있지
칼은 던지기도 돼!

 

 

2. 클래스 변수

 

  클래스 변수는 해당 클래스에서 공통화된 변수이다. 1편에서 클래스 내부 변수에 대해서 다룬 적이 있었는데 그때는 알지 못했어서 추가 정리해본다.

 

class Weapone:
   what = "무기 클래스"

#sword, gun 객체 생성(동일 클래스)
sword = Weapone()
gun = Weapone()

#객체 what 호출
print("sword의 분류 :", sword.what)
print("gun의 분류 : ", gun.what)
print("\n")

#클래스 Weapone 명으로 접근하여 what 수정
Weapone.what = "알게뭐니"

print("sword의 분류 :", sword.what)
print("gun의 분류 : ", gun.what)
print(id(sword.what))
print(id(gun.what))
print("\n")

#sword 객체의 what으로 접근하여 수정
sword.what = "무기 클래스에 속하는 칼"

print("sword의 분류 :", sword.what)
print("gun의 분류 : ", gun.what)
print(id(sword.what))
print(id(gun.what))
print("\n")

 

<결과>

 

#아무 것도 안했을 때
sword의 분류 : 무기 클래스
gun의 분류 :  무기 클래스

#Weapone.what을 수정했을 때(class 변수로 접근)
sword의 분류 : 알게뭐니
gun의 분류 :  알게뭐니
2162532364176
2162532364176

#sword.what만 수정했을 때(객체 변수로 접근)
sword의 분류 : 무기 클래스에 속하는 칼
gun의 분류 :  알게뭐니
2162533955824
2162532364176

 

-. 아무것도 안 했을 때 : class 초기에 정의된 값을 읽어옴.

-. Weapone.what(클래스 변수)를 수정하면 공통적으로 수정됨

-. 참고로 id 함수는 객체의 고유 번호를 읽어오는 함수이다. 번호가 동일하면 동일한 객체라고 한다.

-. 마지막 sword.what(객체 변수)를 수정하니 id가 달라지는 것을 확인할 수 있다. 수정과 동시에 서로 다른 객체가 된다.

 

 


참고 링크 1 : 코딩 도장 dojang.io/mod/page/view.php? id=2389

참고 링크 2 : 위키 독스 - '점프 투 파이썬' wikidocs.net/28

728x90