인공지능 AI

D+36 [Python] OOP(객체지향프로그래밍), Class 개념과 활용

goodjop79 님의 블로그 2026. 5. 29. 00:28

ㅇ 일  자 :  2026년 5월 29일(목)

제  목 : OOP(객체지향프로그래밍), Class 개념과 활용 

 

1. 서  론

  현대 소프트웨어 개발 환경은 과거에 비해 비교할 수 없을 만큼 복잡해지고, 요구사항은 끊임없이 변화하고 있다.
초기 프로그래밍 방식이었던 절차지향 프로그래밍은 프로그램을 단순히 명령어의 순차적인 실행으로 보았기에, 규모가 커질수록 코드를 이해하고, 수정하고, 유지보수하는 것이 기하급수적으로 어려워지는 한계에 봉착했다.
  이러한 한계를 극복하고 더 유연하고 재사용 가능한 소프트웨어를 만들기 위해 등장한 것이 바로 객체지향 프로그래밍(OOP)이다. 객체지향프로그래밍(OOP)는 "현실 세계의 사물과 개념"을 프로그램의 독립된 단위인 '객체'로 모델링하여 프로그램을 구성한다.
  신입 개발자가 OOP의 핵심 개념과 구현하는 도구인 Class를 반드시 이해하고 적용해야 하는 이유는 다음과 같다.
  첫째, 유지보수성 향상이다. 프로그램이 거대해질수록 스파게티 코드처럼 엉킨 코드는 수정할 때마다 새로운 버그를 유발한다. OOP는 코드 간의 '의존성'을 줄이고 독립된 '객체' 단위로 관리하여, 변화에 유연하게 대처할 수 있게 한다.
  둘째, 코드 재사용성이다. 잘 설계된 Class는 다른 프로젝트나 프로그램의 다른 부분에서 그대로 재사용할 수 있어 개발 속도를 높이고 중복 코드를 줄여준다.
  셋째, 협업의 용이성이다. OOP를 기반으로 한 설계는 코드의 의미를 명확하게 전달하며, 각 개발자가 독립된 객체나 모듈을 담당하여 개발할 수 있는 구조를 제공한다.
따라서 신입 개발자에게 OOP와 Class는 단순히 지나쳐가는 기술이 아니라, 복잡한 현대 소프트웨어 개발 환경에서 살아남고 성장하기 위해 반드시 갖춰야 할 필수적인 기술적 체력이자 기본기라고 할 수 있다. 

가. 신입개발자가 갖춰야 할 기술적 목표는 무엇인가?

(1) 신입 개발자의 현실적인 기술 목표
    신입개발자는 프로그래밍 이라는 소프트웨어 개발의 각 단계를 이해하고 이를 바탕으로 자신이 만든 Project 라는 소프트웨어 결과를 Portfolio 에 정리해야 한다. 신입 개발자의 참신함은 ‘전체 흐름’을 꿰뚫는 Portfolio 구축에 있다. "class까지는 순차적인 학습이 가능하지만 이후는 내용이 순차적이 아니라 복합적인 교육이 진행된다".
프로그래밍이라는 소프트웨어 개발의 각 단계를 올바르게 이해하고, 그 결과를 Project 기반의 Portfolio로 증명해 내야 한다. 

  • 포함할 영역: 암호화, 권한 관리, 배포 환경 구축
  • 제외할 영역: 장애 대응, 대용량 로그 및 모니터링 (현실적으로 신입 단계에서는 어렵다)

 

2. 본 론

가. OOP (객체지향 프로그래밍) 이란 무엇인가?

(1) 의 미

     OOP(Object-Oriented Programming, 객체 지향 프로그래밍)는 프로그램을 단순히 명령어의 순차적인 나열로 보는 것이 아니라, 데이터와 기능을 가진 독립된 단위인 '객체(Object)'들의 집합과 상호작용으로 파악하는 프로그래밍 패러다임이다.
 

(2) 등장 배경

     초기 컴퓨터 프로그래밍은 하드웨어를 직접 제어하는 기계어와 어셈블리어를 거쳐, 인간의 언어와 유사한 고급 언어(C 등)를 사용하는 절차지향 프로그래밍으로 발전 했다. 절차지향은 문제를 잘게 쪼개어 순서대로 해결하는 방식에 탁월하여 초기 소프트웨어 개발을 주도했다. 하지만 하드웨어 성능의 발전과 함께 소프트웨어의 규모와 복잡도가 상상 이상으로 커지면서 문제가 발생했다.

  • 스파게티 코드: 프로그램의 각 부분이 서로 밀접하게 연결되어(높은 결합도) 코드 한 줄을 수정하면 프로그램의 전혀 다른 부분에서 예측할 수 없는 오류가 발생했다.
  • 유지보수의 어려움: 코드를 이해하고 수정하는 데 드는 비용이 새로운 프로그램을 만드는 비용을 넘어서는 '소프트웨어 위기'가 발생했다.
  • 코드 재사용의 한계: 비슷한 기능을 하는 코드를 다른 프로그램에서 다시 사용하기가 매우 어려워, 매번 새로운 코드를 작성해야 했다.

이러한 문제를 해결하기 위해, 현실 세계의 '객체(Object)'라는 개념에 주목하게 되었다.
현실 세계의 사물(예: 자동차)은 고유한 데이터(색상, 속도)와 기능(달리기, 멈추기)을 가지고 있으며, 다른 사물과 상호작용 한다.
프로그램 또한 이처럼 독립된 데이터와 기능을 가진 '객체'들의 집합으로 구성하고, 이 객체들이 서로 메시지를 주고받으며(함수 호출) 작동하게 함으로써, 코드 간의 연결 고리를 끊고(낮은 결합도) 각 객체의 독립성을 높여(높은 응집도) 복잡도를 관리하고 재사용성을 높이고자 탄생한 것이 바로 객체지향 프로그래밍 이다.
 

(3) 객체지향 이후의 학습은 '순환선'

신입 개발자의 현실적인 기술 목표에서 언급했듯, 기초 문법부터 Class 기초까지는 순차적으로 학습할 수 있다.    하지만 OOP의 실제 활용과 심화 학습은 단선적인 도로가 아니라 복합적인 개념들이 서로 얽혀있는 '순환선'과도 같다.

단계별 순차적 학습 구간 : 디자인패턴 - 추상화 - 인터페이스 - 솔리드(객체지향)원칙 - 이벤트대리인) - 디자인패턴

 

(4) 핵심 개념 3가지

  • 클래스(Class): 객체를 만들기 위한 설계도 또는 틀
  • 객체(Object): 설계도를 바탕으로 메모리에 구현된 실체
  • 메서드(Method): 객체가 수행할 수 있는 행동이나 기능(함수)

 
(5) OOP의 4대 특징

  • 캡슐화 (Encapsulation)
    • 데이터와 데이터를 처리하는 함수를 하나로 묶는다
    • 외부에서 객체 내부 정보에 직접 접근하지 못하도록 숨겨 데이터를 보호(정보 은닉)
  • 상속 (Inheritance)
    • 자식 클래스가 부모 클래스의 속성과 기능을 그대로 물려받는다
    • 이미 만든 코드를 재사용하여 중복 코드를 줄이고 확장성을 높인다.
  • 다형성 (Polymorphism)
    • 하나의 역할이나 메서드가 상황에 따라 다양한 방식으로 동작하는 성질
    • 하위 클래스에서 메서드를 재정의하는 오버라이딩(Overriding)이 대표적인 예시
  • 추상화 (Abstraction)
    • 복잡한 현실 세계의 사물에서 필요한 공통 속성과 핵심 기능만 추출하여 모델링하는 과정
    • 불필요한 세부 사항은 숨기고 중요한 개념에 집중할 수 있게 한다.

나. Class 예시를 통한 개념 이해 

유아교육을 위한 동물 사운드 및 분류 앱의 시각화 설계도입니다. 객체 지향 프로그래밍(OOP)의 상속(Inheritance) 개념을 깊이 있게 적용하여, 동물이라는 공통 설계도를 바탕으로 조류, 포유류, 어류라는 중간 분류를 만들고, 최종적으로 독수리, 호랑이, 상어라는 구체적인 객체를 효율적으로 구현한다.
 

(1) 동물 사운드 앱 : 깊은 상속 다이어그램

이 다이어그램은 부모 클래스인 '동물'에서 시작하여, 각 동물의 생물학적 분류를 '자식 클래스'로 정의하고, 최종적으로 구체적인 동물 종류를 '손자 클래스'로 정의하는 3단계 계층 구조를 보여준다. 이를 통해 공통 속성과 기능을 최상위 클래스에서 정의하고 하위 클래스에서 이를 확장 및 재사용하는 구조를 시각화 한다.
※ '동물 - 조류 - 포유류 - 어류'는 계층 구조상 모호한 표현이 있어, 표준적인 '조류, 포유류, 어류' 계층 구조로 정리하였음.

 
(2) 구조 설계 상세 설명

  • 최상위 부모 클래스: 동물 (Animal)
    • 모든 동물들이 공통으로 가지는 기본 틀
    • 속성(Attributes) : 이름(name)
    • 기능(Methods) : 소리를 재생하는 버튼 동작(playSound)
  • 중간 자식 클래스 (분류) : 조류, 포유류, 어류
    • 부모 클래스(Animal)를 상속받아 생성되며, 각 분류의 공통 속성이나 기능을 추가할 수 있다. 여기선 예시를 위해 직접 상속을 보여 준다.
  • 최하위 자식 클래스 (손자): 구체적인 동물 종류
    • 해당하는 중간 분류 클래스를 상속받아, 각 동물에 맞는 고유한 소리(sound)만 따로 설정
    • 독수리 (Eagle): sound = "끼에엑"
    • 호랑이 (Tiger): sound = "어흥"
    • 상어 (Shark): sound = "(무소음)"

(3) 파이썬 코드 구현 예시

       이 구조를 활용해 실제 웹이나 앱에서 버튼을 누를 때 소리가 나도록 파이썬으로 프로그래밍 한다. 

# 1. 최상위 부모 클래스 정의
class Animal:
    def __init__(self, name):
        self.name = name

    def play_sound(self):
        # 자식 클래스에서 sound 속성을 정의해야 함을 명시 (강제성 부여)
        raise NotImplementedError("Subclass must implement abstract attribute 'sound'")


# 2. 중간 자식 클래스 정의 (분류)
class Aves(Animal): # 조류
    def __init__(self, name):
        super().__init__(name)

class Mammalia(Animal): # 포유류
    def __init__(self, name):
        super().__init__(name)

class Pisces(Animal): # 어류
    def __init__(self, name):
        super().__init__(name)


# 3. 최하위 자식 클래스 정의 (손자, 구체적인 동물)
class Eagle(Aves): # 독수리는 조류
    def __init__(self):
        super().__init__("독수리")
        self.sound = "끼에엑"

    def play_sound(self): # 오버라이딩: 각자 고유한 소리 출력
        print(f"{self.name}이(가) 하늘에서 '{self.sound}'! 소리를 냅니다.")

class Tiger(Mammalia): # 호랑이는 포유류
    def __init__(self):
        super().__init__("호랑이")
        self.sound = "어흥"

    def play_sound(self): # 오버라이딩
        print(f"{self.name}이(가) 숲속에서 '{self.sound}'! 소리를 냅니다.")

class Shark(Pisces): # 상어는 어류
    def __init__(self):
        super().__init__("상어")
        self.sound = "(무소음)" # 상어는 소리를 내지 않음

    def play_sound(self): # 오버라이딩: 소리가 없는 경우에 대한 구현
        print(f"{self.name}이(가) 바다 속에서 {self.sound}으로 헤엄칩니다.")


# 4. 객체 생성 및 실행 (버튼 클릭 시 동작 시뮬레이션)

# 예시: 각 분류별로 손자 객체 생성
eagle_button = Eagle()
tiger_button = Tiger()
shark_button = Shark()

# 예시: 독수리 버튼 클릭
eagle_button.play_sound() 
# 출력: 독수리이(가) 하늘에서 '끼에엑'! 소리를 냅니다.

# 예시: 호랑이 버튼 클릭
tiger_button.play_sound()
# 출력: 호랑이이(가) 숲속에서 '어흥'! 소리를 냅니다.

# 예시: 상어 버튼 클릭 (소리 대신 메시지)
shark_button.play_sound()
# 출력: 상어이(가) 바다 속에서 (무소음)으로 헤엄칩니다.

 
이처럼 계층적인 설계를 하면, 새로운 동물(예: 참새)이 추가되더라도 기존의 조류(Aves) 클래스를 상속받아 이름과 소리만 정의해주면 매우 쉽게 기능을 확장할 수 있다. 상위 클래스(Animal, Aves 등)의 코드를 건드릴 필요가 없어 안정적이다.


 
다. 프로그램 작성시 우리는 왜  파일(.py)을 분리 해야 하는가? 
    위젯의 통합 코드를 여러 파일(main.py,  Widget.py,  from_tab.py,  buttons_tab.py 등)로 분리하여 사용하는 가장 큰 이유는 
유지보수의 편의성과 코드의 재사용성 때문이다. 코드가 한 파일에 모두 모여 있으면 초기 개발은 빠를 수 있지만, 프로그램이 커질수록 "수정"과 "관리"가 불가능해 진다. 그러므로 분야별 분담과 유지보수 편의성을 위해 class부분을 분리하여 관리한다.
 
   (1) 파일별 역할 분담 구조 (예시)
       - main.py : 프로그램의 시작점. 전체 애플리케이션을 실행하고 메인 윈도우를 띄우는 진입로 역할
       - Widget.py : 메인 화면의 큰 틀이나 공통 레이아웃을 정의하고 조각 파일들을 하나로 조립하는 본체 역할
       - form_tab.py : 입력창, 콤보박스 등 데이터 입력과 관련된 UI와 로직만 집중적으로 관리
       - buttons_tab.py: 버튼의 배치와 버튼을 눌렀을 때 실행될 기능(이벤트)만 따로 모아 관리
 
   (2) 소스코드를 분리하는 핵심 이유
       - 가독성 향상 : 한 파일이 수천 줄이 되는 것을 방지하여 코드를 쉽게 읽을 수 있다.
      - 유지보수 용이 : 버튼 기능을 수정할 때 buttons_tab.py만 열어서 고치면 되므로 다른 코드를 건드릴 위험이 줄어든다.
      - 코드 재사용 form_tab.py에서 만든 입력 양식을 다른 화면이나 다른 프로젝트에서 그대로 가져다 쓸 수 있다.
      - 협업 수월 : 여러 개발자가 동시에 작업할 때, 파일이 분리되어 있으면 깃(Git) 충돌 없이 각자 맡은 화면을 개발할 수 있다.
 
※ 예시 : main.py 설명 
   from PyQt6.QtWidgets import QWidget   # 또는 PySide6.QtWidgets
   class Widget(QWidget) :   # QWidget(기본 위젯 클래스)을 상속받아 새로운 위젯 클래스를 정의함
   def __init__(self, parent=None) :  # 클래스가 생성될 때 자동으로 실행되는 초기화 메서드(생성자)
        super().__init__(parent) :   # 부모 클래스(QWidget)의 생성자를 호출해 위젯을 초기화, 부모-자식 관계 설정
 

3. 결  론  

결국 객체지향 프로그래밍(OOP)은 현대 소프트웨어 개발에서 복잡성을 관리하고 변화에 유연하게 대응하기 위한 가장 강력한 무기이다. 그리고 이러한 OOP의 철학을 실제 코드로 구현해 내는 핵심 도구가 바로 클래스(Class) 이다.
클래스는 복잡한 현실 세계의 개념을 추상화하여 안전하게 묶어두는 설계도 역할을 한다.  개발자는 잘 설계된 클래스를 바탕으로 코드의 중복을 획기적으로 줄이고(상속), 내부 데이터를 안전하게 보호하며(캡슐화), 상황에 따라 유연하게 대처하는 코드(다형성)를 작성할 수 있다.
신입 개발자에게 클래스를 올바르게 이해하고 적용하는 것은 단순한 문법 습득을 넘어, 거대하고 복잡한 소프트웨어 생태계로 진입하기 위한 첫 단추다. 클래스라는 기본 설계도를 탄탄히 다질 때, 비로소 고도화된 디자인 패턴이나 아키텍처라는 넓은 구조를 이해하고 다룰 수 있는 진정한 기술적 성장을 이룰 수 있을 것이다. "도전은 계속된다".


※ 기타 참고

<스파게티 코드>
ㅇ 1970년대 후반~1980년대 컴퓨터 학계의 공식 등장 :  '스파게티'라는 비유가 문헌에 등장하기 시작한 것은 1970년대 후반
- 1978년 Guy Steele이 저술한 맥카시(McCarthy)의 LISP 역사 관련 논문 등에서 프로그램 구조가 엉킨 모습을 '스파게티'에 비유하기 시작했다.
- 이후 1980년대 후반, ISO(국제표준화기구)의 워킹 그룹 문서 등에서 "구조화되지 않고 제어 흐름이 복잡하게 뒤틀린 소스 코드"를 공식적으로 'Spaghetti Code'라고 명명하면서 업계 표준 용어로 자리 잡았다.
ㅇ 1990년대 '안티패턴(Anti-Pattern)'으로 정의
1998년 출간된 소프트웨어 공학의 명저 《안티패턴(AntiPatterns)》 책에서 소프트웨어 개발 시 절대 하지 말아야 할 대표적인 실패 사례(디자인 안티패턴) 중 하나로 '스파게티 코드'를 공식 등록하면서 오늘날까지 널리 쓰이게 되었다.
요약하자면 스파게티 코드는 "코드가 얽히고설켜 유지보수가 불가능한 상태"를 뜻하며, 그 근거와 어원은 1960~70년대 무분별한 GOTO문 사용으로 코드가 뒤엉키는 현상을 소프트웨어 공학자들이 스파게티 면발에 비유하여 비판한 데서 유래했다.    이를 방지하기 위해 탄생한 대표적인 패러다임이 바로 '객체지향 프로그래밍(OOP)'과 '클래스(Class) 기반 설계' 이다.  끝.

 
 

'인공지능 AI' 카테고리의 다른 글

D+33 [SQL] 빅쿼리(BigQuery)가 뭐야?  (0) 2026.05.26