Study/SWEA

[SWEA] [파이썬 프로그래밍 기초(2) 파이썬의 기본 응용] 5. 객체지향

줴림 2025. 4. 3. 02:55

PT 끝나고 와서 다시 시작하는 파이썬 기초 공부. 지금 완전 녹초인데 그래도 오늘 하기로 한 건 끝내고 자야 마음 편할 것 같아서 다시 시작.

시작하기 전에 Expert Academy 객체지향 부분만 강의 봤는데 설명 잘하시더라. 물론 막상 '너가 해봐'하는 상황에서는 제대로 못할 것 같지만.

 

1. 국어, 영어수학 점수를 입력받아 합계를 구하는 객체지향 코드를 작성하십시오. 이 때 학생 클래스의 객체는 객체 생성 시 국어영어수학 점수를 저장하며총점을 구하는 메서드를 제공합니다.

class Score:
    def __init__(self, korean, english, math):
        self.__korean = korean
        self.__english = english
        self.__math = math
        
    @property
    def korean(self):		# getter 메서드 - 국어 성적을 읽는다
        return self.__korean
    
    @property
    def english(self):		# getter 메서드 - 영어 성적을 읽는다
        return self.__english
    
    @property
    def math(self):		# getter 메서드 - 수학 성적을 읽는다
        return self.__math
    
    def sum_score(self):
        sum_score = self.__korean + self.__english + self.__math
        print(f"국어, 영어, 수학의 총점: {sum_score}")
        
scores = list(map(int, input().split(', ')))
scores_list = Score(scores[0], scores[1], scores[2])	# Score 클래스로 만들고 각각 요소를 인자 전달 (여기서 getter 사용해서 읽는 듯)
scores_list.sum_score()

처음은 살짝~ 헷갈려서 인터넷의 고수님들의 코드를 보면서 오류 수정하고 틀린 부분 찾고 그랬다. class 짜는 것도 어색하고 getter 메서드 사용하는 것도 이해를 못해서 헤매고 있었다. 이해하기 위한 수단 중 하나로 한 게 주석 써놓기(...)

 

2. 국적을 출력하는 printNationality 정적 메서드를 갖는 Korean 클래스를 정의하고 메서드를 호출하는 코드를 작성해봅시다.

이것도 차근차근 해보자. 정적 메서드가 뭔지 몰라서 일단 인터넷 검색.
찾아보니까 정적 메서드인스턴스를 통하지 않고 클래스에서 바로 호출할 수 있는 메서드라고 한다. 그럼 __init__은 안 써도 되는 거?

class Korean:
    def printNationality():
        print("대한민국")
Korean.printNationality()
Korean.printNationality()

 

 

3. name 프로퍼티를 가진 Student를 부모 클래스로 major 프로퍼티를 가진 GraduateStudent 자식 클래스를 정의하고 이 클래스의 객체를 다음과 같이 문자열로 출력하는 코드를 작성하십시오.

벌써 부모 클래스가 어쩌고, 자식 클래스가 어쩌고... 하지만 꿀잠을 자기 위해서라면 극복해내야 한다.

class Student:
    def __init__(self, name):
        self.__name = name
    
    @property
    def name(self):
        return self.__name
    
    def __repr__(self):		# 문자열로 출력해야 하니까 작성한다.
        return f"이름: {self.__name}" 
    
class GraduateStudent(Student):		# 자식 클래스 () 안에 부모 클래스 넣기...
    def __init__(self, name, major):
        super().__init__(name)		# 상속할 때는 super().__init__으로 가져온다
        self.__major = major
    
    @property
    def major(self):
        return self.__major
    
    def __repr__(self):
        return super().__repr__() + f", 전공: {self.__major}"		# 마찬가지로 부모 클래스에 있는 메서드도 super().~~로 불러오기

student1 = Student("홍길동")
student2 = GraduateStudent("이순신", "컴퓨터")
print(student1)
print(student2)

여기서 __repr()__이 쓰였는데, 사용 목적이 문자열로 객체를 다시 생성한다고 한다. 좀더 쉬운 설명을 찾아보니까 '문법에 들어간 것을 출력할 수 있는 문자열 형태로 바꾸어서 돌려주는 함수'라고 한다.추가로 찾은 것 중에, __repr__()과 비슷한 __str__()이 있다고 한다. 근데 두 개의 차이점이 __repr__()은 eval() 함수에 사용할 수 있는데 __str__()은 안된다던가..아 그리고 자꾸 하는 실수 중 하나가 정의한 메서드를 사용할 때 소괄호를 안 붙인다는 것이다. 이걸 왜 까먹을까..
1. __repr__(self): 이건 딱히 함수 명시해서 실행하지 않아도 된다. print(student1.__repr__()) 이딴식으로 부르지 말자.
2. 부모 클래스 상속할 때 자식 클래스의 이름 옆 괄호에 부모 클래스 이름 넣자. (ex. class GraduateStudent(Student):)
3. 부모 클래스에서 인스턴스나 메서드 가져올 때는 super(). 사용하기 (ex. super().__init__(name) / super().__repr__())

 

4. 반지름 정보를 갖고, 원의 면적을 계산하는 메서드를 갖는 Circle 클래스를 정의하고, 생성한 객체의 원의 면적을 출력하는 프로그램을 작성하십시오.

원의 면적... 넓이... π*r^2이었나? 대충 π는 3.14로 계산하면 될 듯 싶다.

class Circle:
    def __init__(self, radius):
        self.__radius = radius
    
    @property
    def radius(self):
        return self.__radius
    
    def calc(self):
        return 3.14 * (self.__radius ** 2)

circle = Circle(2)
print(f"원의 면적: {circle.calc()}")

처음에 이게 뭐지 하면서 쓴 코드가 날아가서 개념 복기하는 마음으로 새로 작성했다. 근데 제출했더니 Fail 나와서 어리둥절해하고 있었는데 "원의 면적:"을 빼먹었단 걸 발견. 정말 많이도 하는 실수다.

 

5. 가로, 세로 정보를 갖고, 사각형의 면적을 계산하는 메서드를 갖는 Rectangle 클래스를 정의하고, 생성한 객체의 사각형의 면적을 출력하는 프로그램을 작성하십시오.

이젠 좀 쉽게 할 수 있을 것 같다!! 아 근데 졸려서 가로 세로 영어로 기억이 안나서 인터넷 찾아봄ㅋㅋ 가로는 width, 세로는 height. 기억해두자.. 곧 오픽인데!!!

class Rectangle:
    def __init__(self, width, height):
        self.__width = width
        self.__height = height
        
    @property
    def width(self):
        return self.__width
    
    @property
    def height(self):
        return self.__height
    
    def calc(self):
        return self.__width * self.__height

rec = Rectangle(2, 10)
print(f"사각형의 면적: {rec.calc()}")

훗 쉽게 끝냈다. Rectangle(2, 10)이 아니고 (4, 5), (5, 4), (10, 2)도 다 가능할 듯.

 

6. Shape를 부모 클래스로 Square를 자식 클래스로 정의하는 코드를 작성하십시오. Square 클래스는 length 필드를 가지며, 0을 반환하는 Shape 클래스의 area 메서드를 length * length 값을 반환하는 메서드로 오버라이딩합니다.

오... 이젠 오버라이딩이 나온다. 너무 무섭다.

class Shape:
    def area(self):
        return 0 		# 뭘 넣으라는 말이 없었음...
    
class Square(Shape):
    def __init__(self, length):
        self.__length = length
    
    @property
    def length(self):
        return self.__length
    
    def area(self):
        return self.__length ** 2
    
square = Square(3)
print(f"정사각형의 면적: {square.area()}")

오버라이딩상속받은 메서드의 내용을 자식 클래스에서 변경하는 것임. 그러니까 super(). 어쩌고는 안 써도 됨!
근데 이름만 비슷한 오버로딩(overloading)라는 것이 있다. 오버로딩은 같은 이름의 메소드를 매개변수의 타입이나 개수를 다르게 하여 여러 번 정의하는 걸 의미한다. 헷갈리지 말자!

 

7. Person를 부모 클래스로 Male, Female 자식 클래스를 정의하는 코드를 작성하십시오. "Unknown"을 반환하는 Person 클래스의 getGender 메서드를 Male 클래스와 Female 클래스는 "Male", "Female" 값을 반환하는 메서드로 오버라이딩합니다.

class Person:
    def getGender(self):
        return "Unknown"
    
class Male(Person):
    def getGender(self):
        return "Male"
    
class Female(Person):
    def getGender(self):
        return "Female"
    
male = Male()
female = Female()
print(male.getGender())
print(female.getGender())

이번 것도 매우 쉽게 끝냈다. 근데 SWEA 사이트 계속 test만 하려고 하면 버퍼링 걸려서 F5 누르고 코드 날아가고의 반복이다. 계속 개념 복기하라고 계시가 내린걸까. 근데 나 자고 싶다고.

 

에 뭐야. 끝났다. 이렇게 파이썬 기초는 끝났다. 내일부터는 "2단계: 언어 사용에는 익숙하지만 SW 문제 및 자료구조/알고리즘에는 익숙하지 않은 분"을 위한 걸... 하려고.... 했는데...

장난 아니게 많구나....!!!!! ㅋㅋㅋ 어쩔 수 없지. 일단 내일은 그나마 잘 알고 있는 List부터 Stack까지 빠르게 끝낸다. 하지만 이번에 기초는 그냥 동영상은 건너뛰고 연습문제만 빠르게 풀었다면, 내일부터는 동영상도 제대로 들으면서 진도를 뺄 것 같다. 오픽 공부는 언제하냐