[Python] 클래스 (2)

ㅎㅎ·2021년 5월 23일
0

Python

목록 보기
16/27




📌 생성자(Constructor)

  • 생성자(Constructor)란 객체가 생성될 때 자동으로 호출되는 메서드를 말함.
class FourCal(): # 클래스를 톧해 객체가 생기고 
    def setdata(self,first,second): # 객체에 숫자를 지정
        self.first = first # 객체변수가 생기고 
        self.second = second
    def add(self): # 객체 a가 입력되고
        result = self.first + self.second #위에서 입력된 숫자가 출력
        return result
    def mul(self): 
        result = self.first * self.second
        return result
    def sub(self): 
        result = self.first - self.second
        return result
    def div(self): 
        result = self.first / self.second
        return result


a = FourCal()
print(a.add())

➡️ FoulCal 클래스를 다음과 같이 실행하면,'FourCal' object has no attribute 'first'라는 오류가 뜬다. 이유는 setdata메서드를 수행해야 객체 a의 객체변수 first와 second가 생성되기 때문이다. 이렇게 객체에 초깃값을 설정해야하 할 필요가 있을때는 setdata와 같은 메서드를 호출하여 초깃값을 설정하기보다는 생성자(Constructor)를 구현하는 것이 안전한 방법이다. 파이썬 메서드 이름으로 __init__를 사용하면 메서드는 자동으로 생성자가 된다. 위 코드에 생성자를 추가하면,

#setdata를 __init__으로 이름만 바꿈.
def __init__(self, first, second):
    self.first = first
    self.second = second

➡️ 이름만 바뀌고 모든게 동일하다. 단 메서드 이름을 __init__으로 했기 때문에 생성자로 인식되어 객체가 생성되는 시점에 자동으로 호출된다. 따라서 실행하면

class FourCal(): 
    def __init__(self, first, second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first + self.second 
        return result
    def mul(self): 
        result = self.first * self.second
        return result
    def sub(self): 
        result = self.first - self.second
        return result
    def div(self): 
        result = self.first / self.second
        return result

a = FourCal(4,2) # first와 second에 해당값을 전달해 객체를 생성해야함.
print(a.add())

➡️ 정상적으로 작동한다. 이때 a.FoulCal()를 수행할때 꼭 first와 second에 해당값을 전달하며 객체를 생성해야 한다. 이때 self에는 생성되는 객체가 first에는 4, second는 2가 전달된다.


📌 클래스의 상속(Inheritance)

  • 상속이란 "물려받다"라는 뜻으로 클래스에 이 개념을 적용할 수 있다. 즉 어떤 클래스를 만들 대 다른 클래스의 긴증을 물려받을 수 있게 만드는 것이다. 이 상속 개념을 사용하여 FoulCal 클래스에 'a의 b제곱' 기능을 추가해보자. FoulCal 클래스는 이미 만들었으므로 이 클래스를 상속하는 MoreFoulCal 클래스는 쉽게 만들 수 있다.
    • class 클래스 이름(상속할 클래스 이름)
#클래스 상속하기 
class MoreFoulCal(FourCal): 
	pass
    
#확인하기
a = MoreFoulCal(4,2)
print(a.add())
print(a.div())
print(a.mul())

➡️ 확인하면 상속받은 FoulCal 클래스의 기능을 모두 사용할수 있음을 확인할 수 있다.

  • 상속을 해야하는 이유?
    보통 상속은 기존 클래스를 변경하지 않고 기능을 추가하거나 기존 기능을 변경하려고 할때 사용한다. 클래스의 기능을 추가하고 싶으면 기존 클래스를 수정하면 되는데 왜 굳이 상속을 받아서 처리해야하는지에 대한 의문이 들 수도 있다. 하지만 기존 클래스가 라이브러리 형태로 제공되거나 수정이 허용되지 않는 상황이라면 상속을 사용해야 한다.
#클래스 상속하기 
class MoreFoulCal(FourCal):
    def pow(self): # 거듭제곱 메서드 추가
        result = self.first ** self.second
        return result

a = MoreFoulCal(4,2)
print(a.pow())

➡️ 거듭제곱을 구하는 pow 메서드를 추가한 후, 수행해보면 MoreFoulCal 클래스로 만든 a객체에 4와 2를 설정한후 pow 메서드를 호출하면 4의 2제곱 즉 16을 돌려준다. 상속은 기존 클래스를 그대로 놔둔 채 클래스의 기능을 확장시킬 때 주로 사용한다.


📌 메서드 오버라이딩

class FourCal(): 
    def __init__(self, first, second):
        self.first = first
        self.second = second
    def add(self):
        result = self.first + self.second 
        return result
    def mul(self): 
        result = self.first * self.second
        return result
    def sub(self): 
        result = self.first - self.second
        return result
    def div(self): 
        result = self.first / self.second
        return result

a = FourCal(4,0)
a.div()

➡️ FoulCal 클래스의 객체 a에 4와 0값을 설정하고 div메서드를 호출하면, 4를 0으로 나누려고 하기때문에 division by zero라는 오류가 뜬다. 이렇게 0으로 나눌 때 오류가 아닌 0을 돌려주도록 만들고 싶다면 어떻게 해야할까?

class SafeFourCal(FourCal): # 상속
    def div(self): # 동일한 이름
        if self.second == 0: #나누는값이 0일때
            return 0
        else:
            return self.first / self.second

a = SafeFourCal(6,0)
print(a.div())

➡️ FourCal 클래스를 상속하는 SafeFourCal을 만들었다. 이때 SafeFourCal 클래스는 FourCal 클래스에 있는 div 메서드를 동일한 이름으로 다시 작성했다. 이렇게 부모 클래스(상속한 클래스)에 있는 메서드를 동일한 이름으로 다시 만드는 것을 메서드 오버라이딩(Overrrding)이라고 한다. 이렇게 메서드를 오버라이딩하면 부모클래스의 메서드 대신 오버라이딩한 메서드가 호출된다. 따라서 이렇게 수정하면 나누는 값이 0이라도 오류가 발생하지 않고 0이 출력된다.


📌 클래스 변수

  • 객체 변수는 다른 객체들에 영향받지 않고 독립적으로 그 값을 유지한다. 하지만 클래스 변수는 객체변수와 성격이 다르다.
class Family:
    lastname = "김" # 클래스 변수
    
#클래스이름.클래스 변수
print(Family.lastname) 

# 객체를 통해서 클래스 변수 사용하기
a = Family()
b = Family()
print(a.lastname)
print(b.lastname)

➡️ 클래스에 선언한 lastname이 클래스 변수. 즉 클래스 안에 변수를 선언해 생성한다. 또한 클래스 변수는 클래스이름.클래스 변수 형태로 사용한다. 그리고 클래스로 만든 객체를 통해 사용할 수 있다.

class Family:
    lastname = "최" # 클래스 변수

# 객체를 통해서 클래스 변수 사용하기
a = Family()
b = Family()
print(a.lastname) #최
print(b.lastname) #최

print(id(Family.lastname))
print(id(a.lastname))
print(id(b.lastname))

#결과 - 다 동일

➡️ 만약에 클래스의 lastname을 "최"라고 클래스 변수 값을 변경하면 클래스로 만든 객체의 lastname값도 모두 변경된다. 즉 클래스 변수는 클래스로 만든 모든 객체에 공유된다. 또한, id함수로 주소를 구하면 다 동일한 메모리를 가리키고 있다는 것을 알 수 있다.

0개의 댓글