객체지향프로그래밍 (OOP: object-oriented programming) 은우리가살고있는실제세계가객체 (object) 들로구성되어있는것과비슷하게, 소프트웨어도객체로구성하는방법이다.
객체는상태와동작을가지고있다. 객체의상태 (state) 는객체의속성이다. 객체의동작 (behavior) 은객체가취할수있는동작 ( 기능 ) 이다.
객체에대한설계도를클래스 (class) 라고한다. 클래스로부터만들어지는각각의객체를그클래스의인스턴스 (instance) 라고한다.
데이터와알고리즘을하나로묶고공용인터페이스만제공하고구현세부사항을감추는것은캡슐화 (encapsulation) 라고한다.
Counter 클래스를작성하여보자. Counter 클래스는기계식계수기를나타내며경기장이나콘서트에입장하는관객수를세기위하여사용할수있다.
class Counter: def reset(self): self.count = 0 def increment(self): self.count += 1 def get(self): return self.count
a = Counter() a.reset() a.increment() print(" 카운터 a 의값은 ", a.get()) 카운터 a 의값은 1
a = Counter() b = Counter() a.reset() b.reset()
생성자 (constructor) 는객체가생성될때객체를기본값으로초기화하는특수한메소드이다.
class Counter: def init (self) : self.count = 0 def reset(self) : self.count = 0 def increment(self): self.count += 1 def get(self): return self.count
메소드는클래스안에정의된함수이므로함수를정의하는것과아주유사하다. 하지만첫번째매개변수는항상 self 이어야한다. class Television: def init (self, channel, volume, on): self.channel = channel self.volume = volume self.on = on def show(self): print(self.channel, self.volume, self.on) def setchannel(self, channel): self.channel = channel def getchannel(self): return self.channel
t = Television(9, 10, True) t.show() t.setchannel(11) t.show() 9 10 True 11 10 True
구현의세부사항을클래스안에감추는것
class Student: def init (self, name=none, age=0): self. name = name self. age = age obj=student() print(obj. age)... AttributeError: 'Student' object has no attribute ' age'
하나는인스턴스변수값을반환하는접근자 (getters) 이고또하나는인스턴스변수값을설정하는설정자 (setters) 이다.
class Student: def init (self, name=none, age=0): self. name = name self. age = age def getage(self): return self. age def getname(self): return self. name def setage(self, age): self. age=age def setname(self, name): self. name=name obj=student("hong", 20) obj.getname()
원을클래스도표시해보자. 원은반지름 (radius) 을가지고있다. 원의넓이와둘레를계산하는메소드도정의해보자. 설정자와접근자메소드도작성한다. 원의반지름 = 10 원의넓이 = 314.1592653589793 원의둘레 = 62.83185307179586
import math class Circle: def init (self, radius=1.0): self. radius = radius def setradius(self, r): self. radius = r def getradius(self): return self. radius def calcarea(self): area = math.pi*self. radius*self. radius return area def calccircum(self): circumference = 2.0*math.pi*self. radius return circumference c1=circle(10) print(" 원의반지름 =", c1.getradius()) print(" 원의넓이 =", c1.calcarea()) print(" 원의둘레 =", c1.calccircum())
우리는은행계좌에돈을저금할수있고인출할수도있다. 은행계좌를클래스로모델링하여보자. 은행계좌는현재잔액 (balance) 만을인스턴스변수로가진다. 생성자와인출메소드 withdraw() 와저축메소드 deposit() 만을가정하자. 통장에서 100 가출금되었음 통장에 10 가입금되었음
class BankAccount: def init (self): self. balance = 0 def withdraw(self, amount): self. balance -= amount print(" 통장에 ", amount, " 가입금되었음 ") return self. balance def deposit(self, amount): self. balance += amount print(" 통장에서 ", amount, " 가출금되었음 ") return self. balance a = BankAccount() a.deposit(100) a.withdraw(10)
고양이를클래스로정의한다. 고양이는이름 (name) 과나이 (age) 를속성으로가진다. Missy 3 Lucky 5
class Cat: def init (self, name, age): self. name = name self. age = age def setname(self, name): self. name = name def getname(self): return self. name def setage(self, age): self. age = age def getage(self): return self. age missy = Cat('Missy', 3) lucky = Cat('Lucky', 5) print (missy.getname(), missy.getage()) print (lucky.getname(), lucky.getage())
상자를나타내는 Box 클래스를작성하여보자. Box 클래스는가로길이, 세로길이, 높이를나타내는인스턴스변수를가진다. (100, 100, 100) 상자의부피는 1000000
class Box: def init (self, width=0, length=0, height=0): self. width = width self. length = length self. height = height def setwidth(self, width): self. width = width; def setlength(self, length): self. length = length; def setheight(self, height): self. height = height; def getvolume(self): return self. width*self. length*self. height def str (self): return '(%d, %d, %d)' % (self. width, self. length, self. height) box = Box(100, 100, 100) print(box) print(' 상자의부피는 ', box.getvolume())
자동차를나타내는클래스를정의하여보자. 예를들어, 자동차객체의경우, 속성은색상, 현재속도, 현재기어등이다. 자동차의동작은기아변속하기, 가속하기, 감속하기등을들수있다. 이중에서다음그림과같은속성과동작만을추려서구현해보자. (100, 3, white)
class Car: def init (self, speed=0, gear=1, color="white"): self. speed = speed self. gear = gear self. color = color def setspeed(self, speed): self. speed = speed; def setgear(self, gear): self. gear = gear; def setcolor(self, color): self. color = color; def str (self): return '(%d, %d, %s)' % (self. speed, self. gear, self. color) mycar = Car() mycar.setgear(3); mycar.setspeed(100); print(mycar)
우리가작성한객체가전달되면함수가객체를변경할수있다. # 사각형을클래스로정의한다. class Rectangle: def init (self, side=0): self.side = side def getarea(self): return self.side*self.side # 사각형객체와반복횟수를받아서변을증가시키면서면적을출력한다. def printareas(r, n): while n >= 1: print(r.side, "\t", r.getarea()) r.side = r.side + 1 n = n - 1
# printareas() 을호출하여서객체의내용이변경되는지를확인한다. myrect = Rectangle(); count = 5 printareas(myrect, count) print(" 사각형의변 =", myrect.side) print(" 반복횟수 =", count) 0 0 1 1 2 4 3 9 4 16 사각형의변 = 5 반복횟수 = 5
이들변수는모든객체를통틀어서하나만생성되고모든객체가이것을공유하게된다. 이러한변수를정적멤버또는클래스멤버 (class member) 라고한다.
class Television: serialnumber = 0 # 이것이정적변수이다. def init (self): Television.serialNumber += 1 self.number = Television.serialNumber...
파이썬에는연산자 (+, -, *, /) 에관련된특수메소드 (special method) 가있다. class Circle:... def eq (self, other): return self.radius == other.radius c1 = Circle(10) c2 = Circle(10) if c1 == c2: print(" 원의반지름은동일합니다. ")
class Vector2D : def init (self, x, y): self.x = x self.y = y def add (self, other): return Vector2D(self.x + other.x, self.y + other.y) def sub (self, other): return Vector2D(self.x - other.x, self.y - other.y) def eq (self, other): return self.x == other.x and self.y == other.y def str (self): return '(%g, %g)' % (self.x, self.y) u = Vector2D(0,1) v = Vector2D(1,0) w = Vector2D(1,1) a = u + v print( a)
지역변수 함수안에서선언되는변수 전역변수 함수외부에서선언되는변수 인스턴스변수 클래스안에선언된변수, 앞에 self. 가붙는다.
클래스는속성과동작으로이루어진다. 속성은인스턴스변수로표현되고동작은메소드로표현된다. 객체를생성하려면생성자메소드를호출한다. 생성자메소드는 init () 이름의메소드이다. 인스턴스변수를정의하려면생성자메소드안에서 self. 변수이름과같이생성한다.