클래스의 특징은 다음과 같습니다.
1) 코드의 가독성과 유지보수성 : 클래스는 데이터와 관련된 동작(메서드)을 함께 묶어서 표현할 수 있습니다. 이는 코드의 구조를 보다 체계적으로 만들어 유지보수를 용이하게 합니다
2) 추상화와 캡슐화 :
class Animal: def __init__(self, name): self.name = name def make_sound(self): pass # 메서드를 비워둠. 즉, 추상화되어 있음 class Dog(Animal): def make_sound(self): return "멍멍!" class Cat(Animal): def make_sound(self): return "야옹!" # 간단한 예시를 위해 객체 생성 및 메서드 호출 부분은 생략합니다. |
위의 코드에서 Animal 클래스는 동물의 개념을 나타내며, make_sound()라는 메서드를 가지고 있습니다.
하지만 이 메서드는 추상화되어 실제로는 아무 동작도 하지 않습니다(pass 문으로 비워두었습니다).
이처럼 추상화는 클래스가 필요한 동작을 정의하지만, 그 구체적인 동작은 서브 클래스에서 구현하도록 남겨두는 개념입니다.
그리고 각각의 동물 종류를 나타내는 Dog와 Cat 클래스가 있습니다. 이 클래스들은 Animal 클래스를 상속받아 make_sound() 메서드를 오버라이드하여 각각 개와 고양이의 소리를 반환하도록 구현하였습니다.
이렇게 추상화를 통해 동물이라는 개념을 일반화하고, 캡슐화를 통해 각각의 동물 종류는 자신만의 소리를 가지고 있다는 정보를 캡슐화하여 외부로부터 감춥니다.
즉, 캡슐화는 객체의 내부 구현을 외부로부터 감추는 것으로, 데이터와 그 데이터를 조작하는 메서드를 하나로 묶어 외부에서의 직접적인 접근을 제한하여 코드를 보호하고 유지보수를 용이하게 하며, 안정성을 높이는 역할을 합니다
3)인스턴스(객체)와 상속 : 클래스를 사용하면 객체를 생성할 수 있습니다. 객체는 클래스의 인스턴스로, 각각 독립적인 상태를 가질 수 있습니다. 또한, 클래스는 상속을 통해 기존 클래스를 확장하거나 변경하여 새로운 클래스를 만들 수 있는 기능을 제공합니다. 이는 코드 재사용성과 확장성을 높여줍니다.
4)다형성 : 다형성은 동일한 메서드를 호출하더라도 각각의 객체가 적합한 방식으로 그 메서드를 실행하는 능력을 의미합니다. 다형성은 상속과 연관이 깊으며, 상속 관계에 있는 클래스들이 동일한 메서드를 가지고 있을 때 발생합니다.
class Animal: def make_sound(self): pass class Dog(Animal): def make_sound(self): return "멍멍!" class Cat(Animal): def make_sound(self): return "야옹!" # 동일한 메서드 호출 def animal_sound(animal): return animal.make_sound() # 다형성을 이용한 호출 dog = Dog() cat = Cat() print(animal_sound(dog)) # 출력: 멍멍! print(animal_sound(cat)) # 출력: 야옹! |
위의 코드에서 Animal 클래스를 상속하는 Dog와 Cat 클래스를 정의하고, 각각의 클래스에서 make_sound() 메서드를 오버라이딩하여 구현하였습니다.
animal_sound() 함수는 Animal 클래스의 인스턴스를 인자로 받아서 해당 인스턴스의 make_sound() 메서드를 호출하는 함수입니다. 이 함수를 호출할 때 인자로 Dog 클래스의 인스턴스인 dog와 Cat 클래스의 인스턴스인 cat을 전달합니다.
여기서 다형성이 발생합니다. animal_sound() 함수는 전달된 객체의 타입이 무엇이든 상관없이 해당 객체의 make_sound() 메서드를 호출합니다. 이 때, dog는 Dog 클래스의 인스턴스이므로 Dog 클래스의 make_sound() 메서드가 호출되어 "멍멍!"을 반환하고, cat는 Cat 클래스의 인스턴스이므로 Cat 클래스의 make_sound() 메서드가 호출되어 "야옹!"을 반환합니다.
이처럼 다형성을 통해 동일한 인터페이스를 가진 객체들이 각각의 클래스에 맞게 적절히 동작할 수 있도록 합니다.
5)다형성과 오버라이딩 차이점이 뭐에요?
다형성은 같은 메서드 이름을 가진 다양한 클래스의 객체가 서로 다른 방식으로 동작할 수 있는 개념입니다. 오버라이딩은 이러한 다형성을 구현하는 방법 중 하나로, 부모 클래스의 메서드를 자식 클래스에서 재정의하는 것을 말합니다.
class Animal: def speak(self): print("동물이 소리를 냅니다.") class Dog(Animal): def speak(self): print("멍멍!") class Cat(Animal): def speak(self): print("야옹!") # 다형성 animals = [Dog(), Cat()] # Dog와 Cat 객체를 담는 리스트 for animal in animals: animal.speak() # 각 객체의 speak 메서드를 호출하여 다양한 출력이 가능합니다. # 오버라이딩 class Bird(Animal): def speak(self): print("짹짹!") #<--- 자식클래스에서 동일 메서드를 재정의 # Bird 클래스에서는 Animal 클래스의 speak 메서드를 오버라이딩하여 새로운 동작을 구현합니다. bird = Bird() bird.speak() # Bird 클래스의 speak 메서드가 호출됩니다. |
위 코드에서 Animal 클래스는 speak 메서드를 가지고 있습니다. 이 메서드는 기본적으로 "동물이 소리를 냅니다."를 출력합니다. Dog, Cat, Bird 클래스는 각각 Animal 클래스를 상속받으며 speak 메서드를 오버라이딩합니다. 따라서 각각의 객체가 speak 메서드를 호출할 때 다른 결과를 출력하게 됩니다.
6) 인스턴스와 객체의 차이점이 뭐에요?
아주 특수한 경우를 제외하고는 일반적으로 99% 인스턴스와 객체가 동일하다고 생각하면 됩니다.
클래스로 생성한 객체는 모두 인스턴스입니다.
다만, 아래의 코드에서와 같이 클래스를 정의하지 않고 객체를 생성하는 경우를 생각해보겠습니다.
# 클래스를 정의하지 않고 객체를 생성하는 경우 car = {"brand": "Toyota", "model": "Camry"} # 이 경우에는 객체는 있지만, 클래스가 없으므로 인스턴스라고 할 수 없습니다. # 따라서 이 객체는 인스턴스가 아니라 그냥 객체입니다. |
위의 코드에서 car는 딕셔너리로, 자동차의 브랜드와 모델을 저장하는 객체입니다. 하지만 클래스를 정의하지 않았으므로 이 객체는 어떤 클래스의 인스턴스로 생성된 것이 아니며, 따라서 인스턴스라고 보기는 어렵습니다. 이 객체는 단순히 딕셔너리로 생성된 데이터일 뿐입니다.
따라서 이 경우에는 객체는 존재하지만, 클래스가 없으므로 인스턴스라고 할 수 없습니다. 이런 상황에서는 객체가 인스턴스가 되지 않는 것으로 볼 수 있습니다.
7) 실습
(1) 클래스, 객체, 인스턴스에 대해 각 각 설명해 보세요.
클래스는 일종의 틀로 껍데기와 같은 개념입니다. 클래스에는 관련있는 데이터와 함수를 한 데 모아 정의할 수 있습니다. 클래스로 만들어진 결과물을 객체라고합니다.
예를 들어 붕어빵을 찍어내는 틀은 클래스로 볼 수 있고, 붕어방틀에서 찍어낸 실제 붕어빵1, 붕어빵2 등은 객체라고 할 수 있습니다.
객체와 인스턴스는 아주 특수한 경우를 제외하고는 일반적으로 99% 인스턴스와 객체가 동일하다고 생각하면 됩니다.
클래스로 생성한 객체는 모두 인스턴스이며, 다만, 클래스를 정의하지 않고 객체를 생성하는 경우에는 객체이지만 인스턴스라고 할 수는 없겠습니다.
'파이썬 강좌(초급) > 8.클래스' 카테고리의 다른 글
8.클래스 - 6) 메서드오버라이딩 (3) | 2024.04.01 |
---|---|
8.클래스 - 5) 상속 및 다중상속 (3) | 2024.04.01 |
8.클래스 - 4) 멤버변수와 메서드 (3) | 2024.04.01 |
8.클래스 - 3) 생성자 (4) | 2024.04.01 |
8.클래스 - 1)개요 (1) | 2024.04.01 |