7. 객체(1)-객체 생성하기, 상속

2016. 10. 25. 17:00Programming Languages/PYTHON

1)객체 생성

파이썬의 객체에서 초기화 역할을 담당하는 것은 __init__(self) 함수이다.

첫번째 인자는 반드시 self이며, 객체를 생성할 때 받을 객체의 내부 정보를 self 뒤에 인자로 적어주면 된다.

-->이때 self는 객체 내부에서 '자기자신'을 가리키는 변수이다.

-->모든 클래스 정의에 __init__를 포함할 필요는 없지만, __init__를 통해 같은 클래스의 변수끼리 구분을 용이하게 한다.

     예) Jack과 Lucy는 서로 다른 Person이지만, __init__를 이용해 둘을 구분할 수 있을만한 처리를 하지 않으면 내부상으로는 차이가 없을것이다.



아래의 Person클래스는 생성시 sname과 sage를 받아 객체 내부에 각각 name과 age값을 지정하는데 이용한다.


*pass 는 함수나 객체 내에서 아무 행동도 하지 않을 때 쓰는 구문이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
class Person():
    def __init__(self):
        pass
     
class Person():
    def __init__(self, sname, sage):
        self.name=sname
        self.age=sage
    def print(self):
        print(self.name,"is",str(self.age)+"years old.")
 
someone=Person("Jack",12)
 
someone.print()
 
Jack is 12years old.
cs




2)상속

객체 간에는 부모-자식의 상속관계가 성립할 수 있다.

부모 클래스는 super클래스, base클래스라고도 부르며 자식 클래스는 sub클래스, derived클래스 라고 부르기도 한다.


상속은 단순히 객체 간의 상하 관계를 표현하는 데도 용이하지만, 메소드를 효율적으로 재사용하는데에도 큰 의의가 있다.


아래의 예제에서, Cat클래스는 Pet클래스를 상속 받는다. 

-->Cat클래스 정의시 괄호 안에 Pet을 인자로 넣어주면 상속 관계가 성립된다.


초기화 메소드인 __init__를 포함해서 Cat에 정의되지 않고 Pet에만 정의되어 있는 함수라면 모두 Cat에서 상속받아 사용할 수 있다.

하지만 아래의 예제에서 introduce(self) 메소드처럼 Pet과 Cat에 모두 정의 되어있는 함수를 생각해 보자.

Cat에서 introduce메소드를 호출하려고 하면 Pet의 메소드가 아닌 Cat의 고유 메소드가 오버라이딩 되어 불릴 것이다.


자식 클래스에서는 부모 클래스에 없는 새로운 메소드도 정의할 수 있다. 

아래의 예제에서 Cat클래스는 Pet클래스에는 없는 Sleep()이라는 메소드를 추가로 가지고 있다. 

Pet객체에서 Sleep()메소드를 이용하려고 하면 에러가 날 것이다.


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
class Pet():
    def __init__(self,sname,smaster):
        self.name=sname    
        master.name=smaster
    def introduce(self):
        print("I'm",self.master+"'s lovely pet",self.name+"!")
        
class Cat(Pet):
    def introduce(self):
        print("...meow!")
    def sleep(self):
        print("...zzz")
 
Jacky=Pet("Jacky","GY")
Jacky.introduce()
 
#I'm GY's lovely pet Jacky!
 
Sally=Cat("Sally","GY")
Sally.introduce()
 
#...meow!
 
Sally.name
 
#Sally
cs



부모의 메소드를 그대로 상속하는 것 뿐만 아니라, 부모 메소드에게 약간의 도움을 받아 자식 클래스의 메소드를 꾸릴 수도 있다.


자식 클래스에서는 super().원하는메소드(인자)로 부모 클래스의 메소드를 호출할 수 있는데, 이때 메소드의 인자중에서 self는 생략한다.

1
2
3
4
5
6
7
8
9
class Person():
    def __init__(self, name, age):
        self.name=name
        self.age=age
 
class Employee(Person):
    def __init__(self, name, age, position):
        super().__init__(name,age)
        self.position=position
cs



파이썬의 객체에 포함된 모든 속성과 메서드는 public이다. 대신, getter와 setter로 속성에 간접 접근하는 것은 구현할 수 있다.


property는 setter와 getter를 인자로 받아서 좀 더 이해하기 쉬운 코드를 쓸 수 있게 한다.


name=property(getter, setter)과 지정해주면

객체.name으로 getter를 호출할 수 있고 

객체.name = "이름" 으로 간단히 setter를 호출할 수 있다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
class Person():
    def __init__(self, name):
        hidden_name=name
    def get_name(self):
        return self.hidden_name
    def set_name(self, name):
        hidden_name=name
    name=property(get_name,set_name)
 
someone=Person("Jack")
someone.get_name()
 
#Jack
 
someone.set_name("Faul")
someone.get_name()
 
#Faul
 
someone.name
 
#Faul
 
someone.name="Jack"
someone.name
 
#Jack
cs


아래 코드는 위의 코드와 같은 동작을 수행한다.

1
2
3
4
5
6
7
8
9
class Person():
    def __init__(self, name):
        hidden_name=name
    @property
    def get_name(self):
        return self.hidden_name
    @name.setter
    def set_name(self, name):
        hidden_name=name
cs


property()를 사용하는 대신 데커레이터를 이용했다. 데커레이터는 함수의 수정을 용이하게 하는 파이썬의 기능 중 하나이다.


property()에서 getter만 설정하고 setter를 설정하지 않으면 위부로부터 설정할 수 없는 속성을 만드는 것도 가능하다. 

또, getter의 return 값에 계산된 값이나 상수를 넣는 것도 가능하다. 객체 내의 변수로 계산한 값은 해당 변수의 값이 변경될 때마다 수정된다.