Search

객체지향 프로그래밍

객체를 만들기 위해서는 먼저, 클래스를 만들어야 한다.

클래스는 class 키워드와 속성(변수), 그리고 기능(함수)를 이용해서 만든다.
ex) 차 기능과 속성을 가지는 클래스를 만들어보자.
class Car: def __init__(self,col,len): self.color = col self.length = len def doStop(self): print('STOP!!') def doStart(self): print('START!!') def printCarInfo(self): print(f'self.color: {self.color}') print(f'self.length: {self.length}') # 생성자 호출 : Car() car1 = Car('red',200) car2 = Car('blue',300) car1.printCarInfo() car2.printCarInfo() car1.doStop() car1.doStart()
Python
복사
ex) 비행기 기능(착륙/이륙)과 속성(길이,무게,색상)을 가지는 클래스를 만들어보고, 5개의 객체를 만들어보자.
class Airplane: def __init__(self,col,len, wt): self.color = col self.length = len self.weight = wt def doLand(self): print('착륙합니다.') def doDepart(self): print('이륙합니다.') def printAirInfo(self): print(f'self.color: {self.color}') print(f'self.length: {self.length}') print(f'self.weight: {self.weight}') air1 = Airplane('red',72,120000) air2 = Airplane('blue',80,160000) air3 = Airplane('white',77,130000) air4 = Airplane('wine',88,180000) air5 = Airplane('yellow',73,125000)
Python
복사

객체 속성은 변경할 수 있다.

class Airplane: def __init__(self,col,len, wt): self.color = col self.length = len self.weight = wt def doLand(self): print('착륙합니다.') def doDepart(self): print('이륙합니다.') def printAirInfo(self): print(f'self.color: {self.color}') print(f'self.length: {self.length}') print(f'self.weight: {self.weight}') air1 = Airplane('red',72,120000) # air1의 객체 속성 변경 air1.color = 'purple' air1.length = 75 air.weight = 130000 air.printAirInfo() # -> 변경된 정보를 확인할 수 있다.
Python
복사
ex) 계산기 클래스를 만들고 사칙연산을 시행해보자.
class Calculator: def __init__(self): self.number1 = 0 self.number2 = 0 self.result = 0 def add(self): self.result = self.number1 + self.number2 return self.result def sub(self): self.result = self.number1 - self.number2 return self.result def mul(self): self.result = self.number1 * self.number2 def div(self): self.result = self.number1 / self.number2 calculator = Calculator() calculator.number1 = 10 calculator.number2 = 20 print(calculator.add())
Python
복사
scores = [int(input('국어 점수 입력: ')), int(input('수학 점수 입력: ')), int(input('영어 점수 입력: '))] print(scores) copyScores = scores.copy() # scores 와 copyScores 는 다른 객체. 동일한 메모리 주소를 갖고 있는 것일뿐 # 과목별 점수를 10% 올려보자. for 구문 for idx, score in enumerate(copyScores): result = score * 1.1 # 기존 점수가 100점일 경우에는 100을 저장, 나머지는 10% 올린값 저장 copyScores[idx] = 100 if result > 100 else result print(f'이전 점수 평균 : {round(sum(scores) / len(scores),2)}') print(f'이후 점수 평균 : {round(sum(copyScores) / len(copyScores),2)}')
Python
복사

깊은 복사와 얕은 복사

얕은 복사 : 앞서 본 복사로, 객체 주소를 복사하는 것이고 객체는 복사되지 않는 것
깊은 복사 : 객체 자체를 하나 더 복사하는 것.
class TemCls: def __init__(self,n,s): self.number = n self.str= s def printClsInfo(self): print(f'self.number: {self.number}') print(f'self.str: {self.str}') # 얕은 복사 tc1 = TemCls(10,'hello') tc2 = tc1 tc1.printClasInfo() tc2.printClasInfo() # tc2 속성을 변경시키면 tc1의 값도 바뀌게 된다. tc2.number = 20 tc2.str = 'hi' tc1.printClasInfo() tc2.printClasInfo() # 깊은 복사 # 1. 모듈 사용하기 import copy tc1 = TemCls(10,'hello') tc2 = copy.copy(tc1) # tc1가 가리키는 객체와 tc2가 가리키는 객체가 달라지게 된다. # 그리고 다시 tc2의 속성값을 변경하게 되면 tc2.number = 20 tc2.str = 'hi' # tc2의 값만 바뀐 것을 확인할 수 있다. tc1.printClasInfo() tc2.printClasInfo()
Python
복사
2.
리스트를 이용해서 얕은 복사, 깊은 복사를 비교해보기
id() 함수를 이용하면 메모리 주소를 확인할 수 있다.
import copy # 얕은 복사 scores = [9,8,7,6,5,4] copyScores = scores print(f'id(scores): {id(scores)}') print(f'id(copyScores): {id(copyScores)}') #id(scores): 4333407680 #id(copyScores): 4333407680 --------------------------------------------------- # 깊은 복사 # 1. for 구문, append() copyScores = [] for s in scores: copyScores.append(s) print(f'id(scores): {id(scores)}') print(f'id(copyScores): {id(copyScores)}') #id(scores): 4376186432 #id(copyScores): 4376307584 ---------------------------------------------------------- # 2. extend() copyScores.extend(scores) print(f'id(scores): {id(scores)}') print(f'id(copyScores): {id(copyScores)}') #id(scores): 4336315968 #id(copyScores): 4336690688 ------------------------------------------------------------ # 3. copy() : 리스트 내장 깊은 복사 함수 copyScores = scores.copy() print(f'id(scores): {id(scores)}') print(f'id(copyScores): {id(copyScores)}') #id(scores): 4338250176 #id(copyScores): 4338250304 ------------------------------------------------------------ # 4. 슬라이싱 : [:] copyScores = scores[:] print(f'id(scores): {id(scores)}') print(f'id(copyScores): {id(copyScores)}') #id(scores): 4368101760 #id(copyScores): 4368101888
Python
복사
playerOriScore = [8.7, 9.1, 8.9, 9.8, 7.9, 9.5, 8.8, 8.3] playerCopScore = playerOriScore.copy() # 깊은 복사 # 최고값과 최저값을 빼기 playerCopScore.sort() playerCopScore.pop() # 최고값 빼기 (현 리스트에서 맨 뒤에 있는 값) playerCopScore.pop(0) # 최저값 빼기 (현 리스트에서 맨 앞에 있는 값) print(f'playerOriScore : {playerOriScore}') print(f'playerCopScore : {playerCopScore}') print(f'Original total : {sum(playerOriScore)}') oriAvg = round(sum(playerOriScore) / len(playerOriScore),2) print(f'Original avg : {oriAvg}') print(f'Copy total : {sum(playerCopScore)}') copAvg = round(sum(playerCopScore) / len(playerCopScore),2) print(f'Copy avg : {copAvg}') print(f'oriAvg - copAvg : {oriAvg - copAvg}') playerOriScore : [8.7, 9.1, 8.9, 9.8, 7.9, 9.5, 8.8, 8.3] playerCopScore : [8.3, 8.7, 8.8, 8.9, 9.1, 9.5] Original total : 71.0 Original avg : 8.88 Copy total : 53.300000000000004 Copy avg : 8.88 oriAvg - copAvg : 0.0
Python
복사

클래스 상속

클래스는 또 다른 클래스를 상속해서 내 것처럼 사용할 수 있다.
class First: def go(self): print(f'[First] go() called!') def back(self): print(f'[First] back() called!') class Second(First): # 클래스 상속 def second(self): print(f'[Second] go() called!') mySecond = Second() mySecond.second() mySecond.go() mySecond.back() #[Second] go() called! #[First] go() called! #[First] back() called!
Python
복사
ex) 덧셈, 뺄셈 기능이 있는 클래스를 만들고, 이를 상속하는 클래스를 만들어서 곱셈과 나눗셈 기능을 추가해보자.
class AddSub: def add(self,n1,n2): return n1 + n2 def sub(self,n1,n2): return n1 - n2 class MulDiv(AddSub): def mul(self,n1,n2): return n1 * n2 def div(self,n1,n2): return n1 / n2 cal = MulDiv() print(f'cal.add(10,20) : {cal.add(10,20)}') print(f'cal.sub(10,20) : {cal.sub(10,20)}') print(f'cal.mul(10,20) : {cal.mul(10,20)}') print(f'cal.div(10,20) : {cal.div(10,20)}') #cal.add(10,20) : 30 #cal.sub(10,20) : -10 #cal.mul(10,20) : 200 #cal.div(10,20) : 0.5
Python
복사

객체가 생성될 때 생성자를 호출하면 __init__ () 가 자동으로 호출된다.

class Calculator(): def __init__(self): print(f'[Calculator] __init__() called!') cal = Calculator() # 객체 생성 및 생성자 호출 # [Calculator] __init__() called!
Python
복사

__init__() 의 역할

속성을 초기화해준다.
1 . 외부에서 매개변수로 값을 받아오는 방식
class Calculator(): def __init__(self,n1,n2): print(f'[Calculator] __init__() called!') self.num1 = n1 self.num2 = n2 cal = Calculator(10,20) # 객체 생성 및 생성자 호출 print(cal.num1) print(cal.num2)
Python
복사
2 . 내부에서 값을 고정시키는 방식
class Calculator(): def __init__(self): print(f'[Calculator] __init__() called!') self.num1 = 10 self.num2 = 100 cal = Calculator() # 객체 생성 및 생성자 호출 print(cal.num1) print(cal.num2)
Python
복사
3 . 혼합
class Calculator(): def __init__(self,n): print(f'[Calculator] __init__() called!') self.num1 = n self.num2 = 100 cal = Calculator(3.14) # 객체 생성 및 생성자 호출 print(cal.num1) print(cal.num2)
Python
복사

상위 클래스 속성 초기화하기 - super()

부모 - 자식 클래스 간 상속이 되어 있을 경우, 기능은 특별한 조건 없이 사용할 수 있지만, 속성 의 경우에는 부모 속성을 사용하고 싶다면 super() 메소드를 넣어줘야 한다.
class Parent(): def __init__(self,pnum1,pnum2): print(f'[Pclass] __init__() called!') self.pnum1 = pnum1 self.pnum2 = pnum2 class Child(): def __init__(self,cnum1,cnum2): print(f'[Cclass] __init__() called!') # 부모 클래스 init 호출하여 속성값 초기화해주기 super().__init__(cnum1,cnum2) self.cnum1 = cnum1 self.cnum2 = cnum2 cls = Child(10,20) # [Cclass] __init__() called! #[Pclass] __init__() called!
Python
복사
ex ) 기말고사 점수와 중간 점수 클래스를 만들고, 기말고사 클래스가 중간고가 클래스를 상속받는 형태로 만들어 총 점수와 평균 점수를 구해보자.
class MidExam: def __init__(self,s1,s2,s3): print(f'[MidExam] __init__() called!') self.mid_kor_score = s1 self.mid_eng_score = s2 self.mid_mat_score = s3 def printScores(self): print(f'mid_kor_score : {self.mid_kor_score}') print(f'mid_eng_score : {self.mid_eng_score}') print(f'mid_mat_score : {self.mid_mat_score}') class EndExam(MidExam): def __init__(self,s1,s2,s3,s4,s5,s6): print(f'[EndExam] __init__() called!') super().__init__(s1,s2,s3) self.end_kor_score = s4 self.end_eng_score = s5 self.end_mat_score = s6 def printScores(self): super().printScores() print(f'end_kor_score : {self.end_kor_score}') print(f'end_eng_score : {self.end_eng_score}') print(f'end_mat_score : {self.end_mat_score}') def getTotalScore(self): total = self.mid_kor_score + self.mid_eng_score + self.mid_mat_score total += self.end_kor_score + self.end_eng_score + self.end_mat_score return total def getAvgScore(self): return self.getTotalScore() / 6 exam = EndExam(85,90,88,75,85,95) exam.printScores() # 총점 확인 exam.getTotalScore() # 평균 확인 exam.getAvgScore() #[EndExam] __init__() called! #[MidExam] __init__() called! #mid_kor_score : 85 #mid_eng_score : 90 #mid_mat_score : 88 #end_kor_score : 75 #end_eng_score : 85 #end_mat_score : 95 #518 #86.33333333333333
Python
복사

다중 상속 - 2개 이상의 클래스를 상속한다

다중상속을 너무 남발하면 안된다.
class Car01: def drive(self): print('drive() method called!') class Car02: def turbo(self): print('turbo() method called!') class Car03: def fly(self): print('fly() method called!') class Car(Car01, Car02, Car03): # 다중 상속 def __init__(self): pass Mycar = Car() Mycar.drive() Mycar.turbo() Mycar.fly() #drive() method called! #turbo() method called! #fly() method called!
Python
복사
class BasicCalculator: def add(self,n1,n2): return n1 + n2 def sub(self, n1, n2): return n1 - n2 def mul(self, n1, n2): return n1 * n2 def div(self, n1, n2): return n1 / n2 class DeveloperCalculator: def mod(self,n1,n2): return n1 % n2 def flo(self, n1, n2): return n1 // n2 def exp(self, n1, n2): return n1 ** n2 def div(self, n1, n2): return n1 / n2 class CalCulator(BasicCalculator,DeveloperCalculator): def __init__(self): pass cal = CalCulator() print(cal.add(10,20)) print(cal.sub(10,20)) print(cal.mul(10,20)) print(cal.div(10,20)) print(cal.mod(10,20)) print(cal.flo(10,20)) print(cal.exp(10,20))
Python
복사

오버라이딩 : 메서드를 재정의한다

두 클래스가 종속관계에 있을 때, 하위 클래스가 상위 클래스의 메서드를 재정의하게 되는 경우를 의미한다.
ex 1)
class Robot: def __init__(self,c,h,w): self.color = c self.height = h self.weight = w def fire(self): print(f'미사일 발사!') def printRobotInfo(self): print(f'self.color : {self.color}') print(f'self.height : {self.height}') print(f'self.weight : {self.weight}') class NewRobot(Robot): def __init__(self,c,h,w): super().__init__(c,h,w) def fire(self): # 오버라이딩 print('레이저 발사!') myRobot = NewRobot('red',200,300) myRobot.printRobotInfo() myRobot.fire()
Python
복사
class TriangleArea: def __init__(self,w, h): self.width = w self.height = h def printTriangleAreaInfo(self): print(f'width : {self.width}') print(f'height : {self.height}') def getArea(self): return self.width * self.height / 2 class NewTriangleArea(TriangleArea): def __init__(self,w,h): super().__init__(w,h) def getArea(self): return str(super().getArea()) + '㎠' ta = NewTriangleArea(7,5) ta.printTriangleAreaInfo() triangleArea = ta.getArea() print(f'triangleArea : {triangleArea}') #width : 7 #height : 5 #triangleArea : 17.5㎠
Python
복사