이름, 나이, 성적을 담을 수 있는 클래스를 만들고, 여러 기능(메소드)을 추가하여 코드를 작성하겠습니다.
구현할 메소드는 아래와 같습니다.
- 이름, 나이, 성적을 인자로 받아 객체를 만드는 생성자
- 현재 객체와 인자로 받은 객체를 비교하여 누구의 성적이 더 높은지 반환하는 문자열 타입 메소드
- 숫자 하나를 인자로 받아 해당 학생의 점수가 숫자보다 높은지 반환하는 boolean 타입 메소드
- 정렬 시 학생들의 번호가 내림차순으로 정렬(점수가 같다면 번호를 오름차순으로 정렬) 될 수 있도록 하는 우선순위 메소드.
객체 지향 언어를 사용하나, 편의를 위해 정보를 은닉하지 않았습니다. 문제 풀이 환경이 아니라면 꼭 은닉화를 하는 것을 권장합니다.
[Java]
import java.io.*;
import java.util.*;
// Comparable로부터 상속받아 compareTo를 사용
class Student implements Comparable<Student> {
// 필드 (변수들)
String name;
int num, score;
// 생성자
public Student(String name, int num, int score) {
this.name = name;
this.num = num;
this.score = score;
}
// 객체를 받아 현재의 학생과 비교하여 누구의 성적이 더 높은지 반환하는 문자열 타입 메소드
public String greaterStudent(Student st) {
String temp;
if (this.score > st.score) temp = this.name;
else if (this.score < st.score) temp = st.name;
else temp = "두 학생의 성적이 같습니다.";
return temp;
}
// 정수 N를 받아 현재 학생의 성적이 N보다 높은지를 반환하는 boolean 타입 메소드
public boolean isHigher(int N) {
if (this.score > N) return true;
else return false;
}
// 객체끼리의 우선순위를 정하기 위해 Comparable에서 상속 받아 온 compareTo 메소드
@Override
public int compareTo(Student st) {
if (this.score == st.score) return this.num - st.num;
return st.score - this.score;
}
}
public class Main {
public static void main(String[] args) throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
// 생성자로 객체 생성
Student st1 = new Student("박형기", 4, 83);
Student st2 = new Student("이건우", 2, 83);
Student st3 = new Student("박세인", 3, 18);
Student st4 = new Student("김현진", 5, 100);
Student st5 = new Student("강지훈", 1, 33);
// 문자열 타입 메소드 작동 확인
System.out.println(st1.greaterStudent(st2));
System.out.println(st2.greaterStudent(st3));
System.out.println(st4.greaterStudent(st5));
System.out.println();
// boolean 타입 메소드 작동 확인
System.out.println(st1.isHigher(83));
System.out.println(st3.isHigher(50));
System.out.println(st4.isHigher(50));
System.out.println();
// compareTo 메소드 작동 확인
Student[] book = new Student[5];
book[0] = st1; book[1] = st2; book[2] = st3; book[3] = st4; book[4] = st5;
Arrays.sort(book);
for (Student st : book) {
System.out.println(st.num + " " + st.name + " " + st.score);
}
}
}
간단한 설명은 주석에 달았습니다.
추가로 compareTo에 대해서는 부연 설명을 하겠습니다.
- 해당 클래스가 Comparable을 상속 받아야 사용이 가능하고, Comparable에 구현된 메소드를 오버라이딩 하는 것이기 때문에 @Overriding을 달아줘야 합니다.
- compareTo는 정수 타입입니다. 음수를 반환하면 현재 값이 비교군보다 앞에 있어야 하고, 양수를 반환하면 그 반대입니다. 0을 반환하면 어떤 정렬을 사용하느냐에 따라 결과가 달라집니다. 0을 반환할 일이 없게 처리를 하는 것이 좋습니다.
- compareTo를 사용하지 않아도 단순 비교는 가능합니다. greaterStudent 메소드를 만들어서 사용한 것처럼 하면 됩니다. 그러나 우선순위 큐나 자바 내부에서 구현한 정렬은 compareTo를 기반(Comparator도 사용)으로 정렬하기 때문에 위 코드처럼 Arrays.sort를 쓰는 경우에는 compareTo를 구현해야 합니다.
[C++]
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
class Student {
public:
// 필드 (변수들)
string name;
int num, score;
// 생성자
Student(string name, int num, int score) {
this->name = name;
this->num = num;
this->score = score;
}
// 객체를 받아 현재의 학생과 비교하여 누구의 성적이 더 높은지 반환하는 문자열 타입 메소드
string greaterStudent(Student st) {
string temp;
if (this->score > st.score) temp = this->name;
else if (this->score < st.score) temp = st.name;
else temp = "두 학생의 성적이 같습니다.";
return temp;
}
// 정수 N을 받아 현재 학생의 성적이 N보다 높은지를 반환하는 bool 타입 메소드
bool isHigher(int N) {
if (this->score > N) return true;
else return false;
}
// 객체끼리의 우선순위를 정하기 위해 <연산자 오버로딩
int operator<(const Student& st) const {
if (this->score == st.score) return this->num << st.num;
return this->score > st.score;
}
};
int main(void) {
ios_base::sync_with_stdio(false);
cin.tie(NULL);
cout.tie(NULL);
// 생성자로 객체 생성
Student st1 = Student("박형기", 4, 83);
Student st2 = Student("이건우", 2, 83);
Student st3 = Student("박세인", 3, 18);
Student st4 = Student("김현진", 5, 100);
Student st5 = Student("강지훈", 1, 33);
// 문자열 타입 메소드 작동 확인
cout << st1.greaterStudent(st2) << '\n';
cout << st2.greaterStudent(st3) << '\n';
cout << st4.greaterStudent(st5) << '\n' << '\n';
// bool 타입 메소드 작동 확인
cout << st1.isHigher(83) << '\n';
cout << st3.isHigher(50) << '\n';
cout << st4.isHigher(50) << '\n' << '\n';
// 연산자 오버로딩 작동 확인
vector<Student> book = vector<Student>();
book.push_back(st1); book.push_back(st2); book.push_back(st3); book.push_back(st4); book.push_back(st5);
sort(book.begin(), book.end());
for (Student st : book) {
cout << st.num << ' ' << st.name << ' ' << st.score << '\n';
}
return 0;
}
간단한 설명은 주석에 달았습니다.
추가로 연산자 오버로딩에 대해서는 부연 설명을 하겠습니다.
- vector 자료구조에서 sort를 할 때, <연산자로 대소구분을 하여 정렬합니다.
- C++에서는 클래스 타입에 대해 연산자를 어떻게 사용할지 명시하지 않으면 오류가 나므로 <연산자가 어떻게 작동될지 새로 명시합니다.
- <연산자를 오버로딩하여 score로 비교함을 알림으로써 명시할 수 있습니다.
[Python]
import sys
br = sys.stdin
bw = sys.stdout
class Student:
# 생성자 (필드가 따로 없음)
def __init__(self, name, num, score):
self.name = name
self.num = num
self.score = score
# 객체를 받아 현재의 학생과 비교하여 누구의 성적이 더 높은지 문자열로 반환하는 메소드
def GreaterStudent(self, st):
temp = ""
if (self.score > st.score): temp = self.name
elif (self.score < st.score): temp = st.name
else: temp = "두학생의 성적이 같습니다."
return temp
# 정수 N를 받아 현재 학생의 성적이 N보다 높은지를 boolean으로 반환하는 메소드
def IsHigher(self, N):
if (self.score > N): return True
else: return False
# 객체끼리의 우선순위를 정하기 위해 <연산자 오버로딩
def __lt__(self, st):
if (self.score == st.score): return self.num < st.num
return self.score > st.score
# 생성자로 객체 생성
st1 = Student("박형기", 4, 83)
st2 = Student("이건우", 2, 83)
st3 = Student("박세인", 3, 18)
st4 = Student("김현진", 5, 1000)
st5 = Student("강지훈", 1, 33)
# GreaterStudent 작동 확인
bw.write(st1.GreaterStudent(st2) + '\n')
bw.write(st2.GreaterStudent(st3) + '\n')
bw.write(st4.GreaterStudent(st5) + '\n' + '\n')
# IsHigher 작동 확인
bw.write(str(st1.IsHigher(83)) + '\n')
bw.write(str(st3.IsHigher(50)) + '\n')
bw.write(str(st4.IsHigher(50)) + '\n' + '\n')
# 연산자 오버로딩 작동 확인
book = []
book.append(st1)
book.append(st2)
book.append(st3)
book.append(st4)
book.append(st5)
book.sort()
for st in book:
bw.write(str(st.num) + ' ' + st.name + ' ' + str(st.score) + '\n')
bw.close()
br.close()
간단한 설명은 주석에 적었습니다.
연산자 오버로딩에 관한 내용은 함수명만 차이가 있고 C++과 동일합니다.
'프로그래밍 언어 정리 > 기초 다지기' 카테고리의 다른 글
[기초 다지기 - 3] 람다 표현식 (0) | 2022.12.22 |
---|---|
[기초 다지기 - 1] EOF (2) | 2022.12.05 |
[기초 다지기 - 0] 빠른 입출력 (0) | 2022.10.23 |