A. 클래스는 함수의 상위 개념이다. 클래스 안에 함수를 작성한다.
메소드는 함수이다. 클래스에 정의된 함수를 사용할 땐 메소드라한다.
함수 = 동작한다 = 메소드
- 클래스는 대분류, 함수는 중분류라고 보자.
흐름에 따라 절차를 따르는 것.
현실 세계의 모든 것을 객체로 만든다. 객체의 상태(state)는 객체의 속성이다.
객체의 동작(behavior)은 객체가 취할 수 있는 기능.
객체 지향형의 경우 프라이빗 함수, 변수 사용이 가능해 보안을 할 수 있다.
속성(== 객체의 상태, state)은 인수이다.
#class 클래스이름:
class Intro:
def __init__(self, age, name):
#self.속성 = 값
self.age = age
self.name = name
class Person:
def __init__(self):
self.hello = '안녕하세요.'
def greeting(self):
print(self.hello)
james = Person()
james.greeting()
========================= RESTART: /Users/boksilhwang/Documents/test.py =========================
안녕하세요.
상태 - 빨간색이다, 채널번호, 볼륨, 전원 상태 등
동작 - 켜다, 끄다, 채널 변경, 볼륨을 높이다. 등
클래스 = 와플 틀, 따라서 클래스는 객체를 찍어내는 틀과 같다.
객체(인스턴스) = 와플 1, 2, 3 ...
객체의 동작 담당 = 메소드 == 함수
캡슐화란 알고리즘과 데이터를 하나로 묶고 내부 코드를 외부로부터 감춘다.
객체 지향은 보안이 된다고 위에서 말했듯 클래스 내부의 코드를 직접적으로 관여할 수 없다.
- '클래스를 만들다' 가 캡슐화 시키다'로 인식해도 되는가?
class 클래스이름:
def 메서드(self):
코드
class Counter :
def reset(self) :
self.count = 0 #정의해줘야 아래에서 + 1을 해줄 수 있음.
#.count는 어디서 나온거지? 단순 카운팅하는 메소드인가?
def increment(self) :
self.count += 1
def get(self) :
return self.count
a = Counter() #변수에 클래스를 할당, a는 객체이기도 하다. 따라서 여러 객체를 만들 수 있다. b = Counter() 등등
a.reset() #.메소드는 함수에 해당한다.
a.increment()
print('카운터 a의 값은', a.get())
#클래스 재활용
b = Counter()
b.reset()
b.increment()
b.increment()
print('카운터 b의 값은', b.get())
class Person: # 코드 부분에 pass를 사용
pass
클래스에서 초기화를 시킨다는 의미는 클래스 내부에 어떠한 값을 정의한다는 의미다.
reset() 함수를 만들어 시작 시 매번 초기화를 시킬 필요 없이__init__
함수를 사용해 별도의 초기화 메소드 사용없이 클래스를 사용할 수 있다.
.reset()
함수를 정의한 후 아래 코드와 같이 .reset()
메소드를 사용 했어야 함.a = Counter() #클래스를 변수에 정의
a.reset() #클래스 초기화
a.increment()
print('카운터 a의 값은', a.get())
b = Counter()
b.reset() #클래스 초기화
b.increment()
print('카운터 b의 값은', b.get())
__init__
함수 사용 시
__init__
는 생성자(constructor)라고 한다.
따라서__init__
는 객체에 reset() 메소드를 쓰지않아도 초기화 할 수 있도록 만들어진 기능.
reset 함수는 코드 진행 후 중간에 reset을 할 일이 있을 때, 따로 reset을 사용하면 된다.
__명령어__
언더바가 두 개인 이유는 파이썬 내부에서 사용한다는 의미.
class Counter :
def __init__(self) :
self.count = 0
a = Counter()
#a.reset() # reset() 없이 바로 사용 가능.
a.increment()
print('카운터 a의 값은', a.get())
initValur = 0
를 인자로 넣어주고, 클래스를 부를 때 클래스에 인수를 넘겨주면 된다. 인수가 없는 경우 기본 값인 0으로 초기화 한다.
class Counter :
def __init__(self, initValur = 0) :
self.count = 0
def increment(self) :
self.count += 1
def get(self) :
return self.count
a = Counter()
a.increment()
print('카운터 a의 값은', a.get()) #결과 값 1
b = Counter(100)
b.increment()
print('카운터 b의 값은', b.get()) #결과 값 101
self는 클래스 외부에 정의된 변수(==self)의 이름을 인수로 가진다.
self에는 변수가 자동으로 들어오기 때문에 인수를 별도로 줄 필요 없다.
class Counter :
def __init__(self, initValur = 0) : #self는 a
self.count = 0
a = Counter()
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()
print(t.getChannel())
__
언더바가 두 개 붙을 경우 클래스 외부에서 변수 변경이 불가하다.
변수에__
을 붙이면obj.name()
으로 프린트해서 바로 가져오진 못 하지만 클래스 내부에 정의된 함수인 obj.getName()으로는 불러 올 수 있다.
한마디로__
을 붙이면 인수를 직접 접근 하는 것이 아닌 함수명(메소드)로만 기능을 실행할 수 있다.
클래스 내 함수에서 인수를 활용한 변수가 없으면 그 값에 대한건 아예 접근이 불가능한거지.
class Student :
def __init__(self, name = None, age = 0) :
self.__name = name
self.__age = age
obj = Student('Hong', 21)
print(obj.__age)
========================= RESTART: /Users/boksilhwang/Documents/test.py =========================
Traceback (most recent call last):
File "/Users/boksilhwang/Documents/test.py", line 7, in <module>
print(obj.__age)
AttributeError: 'Student' object has no attribute '__age'
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) :
if age < 0 :
self.__age = 0
else :
self.__age = age
def setName(self, name) :
self.__name = name
obj = Student('Hong', 20)
name = obj.getName()
print(name)
obj.setAge(-21)
age = obj.getAge()
print(age)
#print(obj.age) # 불가능
print(obj.getAge()) # 가능
#print(obj.age)
#obj.age = -21
#print(obj.age)
#print(obj.getName())
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('원의 넓이 = ', round(c1.calcArea(), 2))
print('원의 둘레 = ', round(c1.calcCircum(), 2))
c1.setRadius(5) #인수가 아닌 메소드로 변경
print(c1.getRadius(), c1.calcArea())
class Dog :
def __init__(self, name=None, age = 0) :
self.__name = name
self.__age = age
def getName(self) :
return self.__name
def getAge(self) :
return self.__age
def setAge(self, age) :
self.__age = age
coffee = Dog('Coffee', 12)
latte = Dog('Latte', 5)
print('{}의 나이는 {}살.'.format(coffee.getName(), coffee.getAge()))
print('{}의 나이는 {}살.'.format(latte.getName(), latte.getAge()))
latte.setAge(4)
print('{}의 나이는 {}살.'.format(latte.getName(), latte.getAge()))
A. 프린트문이 어디에 있냐에 따라 다른 듯. print문이 클래스 내부의 함수 내부에 있으면 a.getAge() 할때 알아서 프린트 할꺼고, 리턴값 자체로는 전달용이지 보여주기 용이 아님. 그러니 보여주고 싶으면 내, 외부에서 프린트문을 사용해야 함.
__str__
와 같이 언더바가 붙은 함수를 특수 메소드라 함.
__str__
함수, 메소드 실행 시 자동 실행.
print(box)
<< 객체자체를 print문에 사용 시__str__
함수가 자동 실행 됨.
__str__
에 출력하고자 하는 내용을 작성 해두면 좋다.
__str__
을 사용해보자.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('상자의 부피는 {}'.format(box.getVolume()))
=============================== RESTART: C:\Users\GIEC\Desktop\기초문법\1031\test.py ==============================
(100, 100, 100) #__str__의 결과 값
상자의 부피는 1000000
__str__
을 사용해보자. 자동차 클래스 만들기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 '(Speed : {}, Gear : {}, Color : {})'.format(self.__speed, self.__gear, self.__color)
#return '(%d, %d, %s)' % (self.__speed, self.__gear, self.__color) #%s의 활용성을 몰라서 .format을 사용함.
car = Car()
car.setSpeed(100)
car.setGear(3)
print(car)
car.setColor('Black')
print(car)
=============================== RESTART: C:\Users\GIEC\Desktop\기초문법\1031\test.py ==============================
(Speed : 100, Gear : 3, Color : White)
(Speed : 100, Gear : 3, Color : Black)
클래스 내에 모든 객체를 통틀어 하나만 생성하여 모든 객체가 이것을 공유, 이러한 변수를 정적 멤버 또는 클래스 멤버하고 한다.
클래스 내부에 있는 변수는 정적 변수(클래스 변수)
정적 변수는 클래스의 변수이므로 함수인__init__
위에 정의 한다.
class Television :
serialNumber = 0 #클래스의 변수
def __init__(self) :
Television.serialNumber += 1
self.number = Television.serialNumber
tv1 = Television()
print(Television.serialNumber)
#외부 변수가 아닌 클래스 변수이므로 `클래스.변수`로 출력할 수 있다.
tv2 = Television()
print(Television.serialNumber)
=============================== RESTART: C:\Users\GIEC\Desktop\기초문법\1031\test.py ==============================
1
2 #따라서 출력 값이 초기화 되지 않고 +1이 더해져 2가 나온다.