🌈 객체 지향 정리
🔥 객체 지향 기본 정리
🔥 객체지향 상속 기능 이해
🔥 클래스 속성과 메서드
1. 객체 지향 기본 정리(사각형 만들기)
- 클래스 선언 및 객체 생성 방법 : 클래스 선언 후, 이를 변수에 담음
- 클래스와 객체는 유사한 내부 메서드를 가지고 있는 것을 볼 수 있음
class helloClass():
pass
make_class = helloClass()
print(dir(helloClass()))
print(dir(make_class))
- attribute 삽입 : width, height, color
- 생성자를 선언한 뒤, 객체를 만들어 dir() 함수로 확인하면, width, height, color 속성이 추가되어 있음
- 즉, 'square1', 'square2'는 객체인데, 이 객체안에 속성이 추가된 것을 볼 수 확인 가능함
- 또한 생성자로 선언한 속성들은 클래스 자체에 dir했을 때는 나타나지 않고, 생성된 객체에서만 존재하는 것을 알 수 있음
class Quadrangle:
def __init__(self, width, height, color):
self.width = width
self.height = height
self.color = color
square1 = Quadrangle(12,12,'red')
square2 = Quadrangle(10,10,'blue')
print(square1)
print(square2)
print(dir(square1))
print(dir(square2))
class Quadrangle:
def __init__(self, width, height, color):
self.width = width
self.height = height
self.color = color
square1 = Quadrangle(10,5,'red')
square2 = Quadrangle(7,7,'blue')
print(square1.width, square1.height, square1.color)
print(square2.width, square2.height, square2.color)
- 메서드 만들기 : 메서드는 class 안에 있는 함수이며, self를 첫번째 파라미터로 받음
- 또한 클래스의 attribute에 접근 시, "slef.속성이름"으로 접근
- self는 객체 자기 자신을 뜻함
- 사각형 넓이를 구하는 메서드 만들기
class Quadrangle:
def __init__(self, width, height, color):
self.width = width
self.height = height
self.color = color
def get_area(self):
return self.width * self.height
square1 = Quadrangle(10,5,'red')
square2 = Quadrangle(7,7,'blue')
print(square1.get_area())
print(square2.get_area())
- Class 안에 메서드를 생성하여 속성값을 바꿀 수 있음
class Quadrangle:
def __init__(self, width, height, color):
self.width = width
self.height = height
self.color = color
def get_area(self):
return self.width * self.height
def set_area(self, data1, data2):
self.width = data1
self.height = data2
square = Quadrangle(2,3,'orange')
square.set_area(5,5)
print(square.width)
print(square.height)
print(square.get_area())
2. 객체지향 상속 기능 이해
- 추상화(abstraction) : 여러 클래스에 중복되는 속성, 메서드를 하나의 기본 클래스로 작성하는 작성
- 상속(ingeritance) : 기본 클래스의 공통 기능을 물려받고, 추가적으로 필요한 부분 및 수정될 부분만 변경하는 것
- 부모 클래스가 둘 이상인 경우는 이를 다중 상속이라고 부름
- issubclass(자식클래스명, 부모클래스명) : 클래스의 상속 관계 확인
- 첫번째 파라미터(자식클래스)가 두번째 파라미터(부모클래스)의 자식인지 확인하여 bool값 return
- 🔍 print(issubclass(Quadrangle, Figure))
class Figure:
def __init__(self, name, color):
self.name = name
self.color = color
class Quadrangle(Figure):
def set_area(self, width, height):
self.width = width
self.height = height
def get_info(self):
print(self.name, self.color, self.width * self.height)
square = Quadrangle('blue_quadrangle', 'blue')
square.set_area(4,4)
square.get_info()
print(issubclass(Quadrangle, Figure))
print(issubclass(Figure, Quadrangle))
- isinstance(객체명, 클래스명) : 해당 객체가 클래스의 소속인지 확인
- 상속해준 부모는 자식에서 만든 객체를 품을 수 있기 때문에 자식에서 만든 객체와 부모클래스를 비교하면 True값을 return
- 🔍 print(isinstance(square, Figure)) 👉 True
- 🔍 print(isinstance(square, Quadrangle)) 👉 True
class Figure:
def __init__(self, name, color):
self.name = name
self.color = color
class Quadrangle(Figure):
def set_area(self, width, height):
self.width = width
self.height = height
def get_info(self):
print(self.name, self.color, self.width * self.height)
figure1 = Figure('a', 'black')
square = Quadrangle('b', 'red')
print(isinstance(figure1, Figure))
print(isinstance(square, Figure))
print(isinstance(figure1, Quadrangle))
print(isinstance(square, Quadrangle))
- 메서드 오버라이딩(덮어쓰기) : 부모 Calss에서 메서드를 생성하고, 이를 상속받은 자식 Class에서 같은 메서드 명으로 메서드를 지정하는 것
- 기존 부모 Class 메서드는 자식 Class메서드에서 덮어씌어 사용하기 때문에 자식 Class로 만든 객체에서 메서드를 호출하면 자식 메서드의 함수가 작동
class Person:
def __init__(self, name):
self.name = name
def work(self):
print(self.name + ' works hard')
class Student(Person):
def work(self):
print(self.name + ' studies hard')
student1 = Student('Jaewon')
student1.work()
- super() : 부모 Class의 메서드를 자식 Class에서 오버라딩했더라도,
super().메서드()
를 통해 재상속 받을 수 있음
class Person:
def work(self):
print('Today work hard!')
class Student(Person):
def work(self):
print('Today study coding!')
def need_money(self):
super().work()
haezin = Person()
jaewon = Student()
haezin.work()
jaewon.work()
jaewon.need_money()
3. 클래스 속성과 메서드
- class 변수 : 정의된 Class에서 메서드 밖에 존재하는 변수
- 해당 클래스를 사용하는 모두에게 공용으로 사용되는 변수로, 클래스 변수는 클래스 내부와 외부에서 "클래스명.변수명"으로 엑세스 가능
- instance 변수 : 정의된 Class에서 메서드 안에서 사용되면서 "self.변수명"으로 사용하는 변수
- 각 객체별로 다른 값을 가지며, 클래스 내부에서는 "self.인스턴스변수명"을 사용하여 엑세스하고, 클래스 외부에서는 "객체명.인스턴스변수명"으로 엑세스
class Figure:
count = 0
def __init__(self, width, height):
self.width = width
self.height = height
Figure.count += 1
def __del__(self):
Figure.count -= 1
def calc_area(self):
return self.width * self.height
figure1 = Figure(2, 3)
print(Figure.count)
figure2 = Figure(2, 3)
print(Figure.count)
del figure1
print(Figure.count)
del figure2
print(Figure.count)
- intance method : 해당 객체 안에서 호출(지금까지 다룬 self.메서드명을 의미함)
- static method : 객체와 독립적이지만, 로직상 클래스내에 포함되는 메서드
- self 파라미터를 갖고 있지 않음
- 객체 속성에 접근 불가(self.변수명 등을 사용할 수 없음)
- 정적 메서드는 메서드 앞에 @staticmethod 라는 데코레이션을 넣어야 함
- "클래스명.정적메서드명" 또는 "객체명.정적메서드명" 두 방법 모두 호출 가능
class Figure:
def __init__(self, width, height):
self.width = width
self.height = height
def calc_area(self):
return self.width * self.height
@staticmethod
def is_square(rect_width, rect_height):
if rect_width == rect_height:
print('정사각형 입니다.')
else:
print('정사각형이 아닙니다.')
figure1 = Figure(2, 3)
figure1.is_square(5,5)
Figure.is_square(4,5)
- class method : 해당 클래스만을 범위를 가지는 메서드
- 해당 클래스로 만들어진 객체로는 호출되지 않고, 직접 클래스 자체에서 호출
- 클래스를 상속이 시켰더라도, 해당 클래스에서만 사용 가능
- self 파라미터 대신, cls 파라미터를 자짐
- 클래스 변수에 접근 가능하며, "cls.클래스명"으로 엑세스 가능(단, 객체 속성/메서드 접근 불가)
- 클래스 메서드는 메서드 앞에 @classmethod 라는 데코레이션 넣어야함
- "클래스명.클래스메서드명" 또는 "객체명.클래스메서드명" 둘다 호출 가능
class Figure:
count = 0
def __init__(self, width, height):
self.width = width
self.height = height
Figure.count += 1
def calc_area(self):
return self.width * self.height
@classmethod
def print_count(cls):
return cls.count
firgure1 = Figure(2,3)
firgure2 = Figure(4,5)
firgure3 = Figure(3,4)
print(Figure.count)
print(Figure.print_count())
print(firgure1.print_count())
- static 메서드와 class method의 차이
- class method는 상속을 했다하더라도 해당 클래스(Circle)에만 영향을 미침
- static method는 상속한 곳에서 적용을 시켜도, 부모 클래스까지 영향을 미침
- class method는 해당 클래스만을 범위로 하고, static method는 별개의 함수처럼 작동함
class Figure:
@classmethod
def set_name(cls, name):
cls.name = name
class Circle(Figure):
pass
Figure.set_name("figure")
print(Figure.name, Circle.name)
Circle.set_name('circle')
print(Figure.name, Circle.name)
class Figure:
@staticmethod
def set_name(name):
Figure.name = name
class Circle(Figure):
pass
Figure.set_name("figure")
print(Figure.name, Circle.name)
Circle.set_name('circle')
print(Figure.name, Circle.name)