본문 바로가기

Programming/Python

상속

객체 지향 프로그래밍의 또 다른 장점은 코드를 재사용 할 수 있다는 것인데
이를 위한 한가지 방법으로 상속이 사용된다.


상속은 클래스 간의 형식과 세부 형식을 구현하는 것이라고 생각해 볼 수 있다.

만일 우리가 어떤 대학의 교수님들과 학생들의 명부를 작성하는 프로그램을 작성한다고 가정하자.
이 때 교수와 학생 모두 공통적으로 이름 , 나이 , 주소 등의 성질을 가지고 있을 것이며 , 
교수에만 적용되는 성질로는 연봉 , 과목 , 휴가 등이 있을 것이고 , 학생에만 적용되는 성질로는 성적 , 등록금 등이 있을 것이다.


따라서 우리는 각각의 경우에 두 독립적인 클래스를 만들 수 있겠지만 , 이 경우 각각의 공통적인 성질 또한 각각의 클래스에
두번씩 반복해서 정의해줘야 한다. ( 여간 귀찮은게 아니다..)

더 나은 방법은 schoolmember 라는 이름으로 공통 클래스를 생성한 뒤 교수와 학생 클래스를 이 클래스로 부터 상속받아 생성하는 것이다.

이 경우 , 상속받은 클래스들은 이를테면 상위 형식(클래스)의 세부 형식이 되는 것이고 , 따라서 이 세부 형식에 각 상황에 맞는 세부적인
성질들을 추가, 수정 등을 해 줄 수 있다.


이러한 접근방식 ( 상속 ) 에는 많은 장점이 있다.
그 중 한가지 장점은 우리가 schoolmember에 새로운 기능을 추가하거나 혹은 있던 기능을 수정하게 되면 , 
그 하위 클래스인 교수와 학생 클래스에도 이러한 변경 사항이 자동으로 추가된다는 점이다
. ( 유지보수 매우 용이 )


예를들어 교수와 학생들에게 새로 출입증을 발급해야 할 경우 schoolmember 클래스에 이를 적용해주기만 하면 된다.
반대로 하위 클래스에 적용된 변경 사항은 다른 하위 클래스에 적용되지 않는다.
또 다른 장점은 우리가 예를들어 대학에 소속된 사람들의 모든 숫자를 파악해야 한다고 할 경우 교수와 학생 객체를

schoolmember 객체로써 참조하여 사용할 수 있다는 점이다.

이것을 다형성 이라고 부르는데 ,  하위 형식이 부모 형식을 필요로 하는 어떤 상황에서건 이를 대신하여 사용될 수 있다는 것을 의미한다.
즉 자식 클래스의 객체를 부모 클래스의 인스턴스인 것 처럼 다룰수 있다.

따라서 상속을 이용하면 부모 클래스의 코드를 재사용할 수 있고 서로 완전히 독립적인 클래스들을 정의했을 때 처럼 각각 다른 클래스에 이를 또 반복해서 써 줄 필요가 없다는 것이다.


이 상황에서 schoolmember 클래스를 기본클래스 혹은 슈퍼클래스 라고 부른다.
그리고 이 클래스의 자식 클래스들을 파생클래스 혹은 서브클래스 라고 부른다.



class schoolmember:                             #클래스 생성
def __init__(self,name,age): #__init__ 메소드 생성 , 인자로 name & age를 받음
self.name = name
self.age = age
print("school member 초기화 : {}".format(self.name))

def tell(self):
print("Name : {} , age : {} ".format(self.name,self.age))

class teacher(schoolmember):
# schoolmember 클래스를 상속받아 teacher 클래스 생성
def __init__(self,name,age,salary):
schoolmember.__init__(self,name,age)
self.salary = salary
print("teacher 초기화 : {}".format(self.name))

def tell(self):
schoolmember.tell(self)
print("Salary : {:d}".format(self.salary))

class student(schoolmember):
# schoolmember 클래스를 상속받아 student 클래스 생성
def __init__(self,name,age,marks):
schoolmember.__init__(self,name,age)
self.marks = marks
print("student 초기화 : {}".format(self.name))

def tell(self):
schoolmember.tell(self)
print("Marks:{:d}".format(self.marks))

t=teacher("Mrs.shrividya",40,30000)
s=student("swaroop",25,75)



members = [t,s]
for member in members:
member.tell()

실행 결과 : 

school member 초기화 : Mrs.shrividya

teacher 초기화 : Mrs.shrividya

school member 초기화 : swaroop

student 초기화 : swaroop

Name : Mrs.shrividya , age : 40 

Salary : 30000

Name : swaroop , age : 25 

Marks:75


기본 클래스의 init 메소드가 self 변수를 이용하여 명시적으로 호출되며 따라서 객체의 기본 클래스에 정의된 초기화 명령들을 호출한다.

즉 , 파이썬은 기본 클래스의 생성자를 자동으로 호출해 주지 않으므로 명시적으로 이것을 호출해 주어야 한다는 점을 기억하자

또한 기본 클래스의 메소드를 호출할 때 클래스 이름을 메소드 호출에 지정해 주었고 또 self 변수에 인수들과 함께 넘겨줬다.

여기서 schoolmember 클래스의 tell 메소드를 사용할 떄 , teacher 나 student와 같은 인스턴스들을 schoolmember의 인스턴스로써 사용한다는 점을 확인하자.

또, 위에서 tell 메소드를 호출할 때 하위 클래스의 메소드가 호출되었고 schoolmember 클래스의 메소드가 호출되지 않았다는것을 확인하자.

즉 , 파이썬은 언제나 해당 형식 ( 클래스 ) 안에서 해당 메소드가 있는지 찾고 , 여기서 메소드를 찾지 못한 경우 그 클래스의 기본 클래스를 한 단계씩 찾아 올라가면서 해당 메소드가 있는지 계속 확인한다는 것을 기억하면 이해하기 쉽다.



'Programming > Python' 카테고리의 다른 글

예외 처리  (0) 2017.11.13
입력과 출력  (0) 2017.11.13
클래스 변수와 객체 변수  (0) 2017.11.13
객체 지향 프로그래밍 ( Object - Oriented Programming )  (0) 2017.11.12
문자열 보충설명  (0) 2017.11.11