시간이 참 빨리 가서 다행이다. 안 갈 줄 알았던 시간인데 알차게 잘 보내고 있는 것 같아서 조금 마음이 놓인다. 94일 중 오늘로 11일째! 벌써 10%가 넘게 출석했다는 이야기다! 팀원들과 이런 이야기 하며 오늘도 참 하루가 빠르게 흘러갔다고 얘기했다. 그리고 확실히 Level 2과제를 풀어보니 1과 달리 아직 자유자재로 코드를 다루고, 빠르고 효율적으로 코드를 작성하지는 못하는 점이 아쉬웠다. 아직 배울 것도 많고, 열심히 노력해야 할 부분들도 참 많이 남은 것 같다. 그래도 하기 싫다거나, 재미없다는 생각은 자바 공부를 하면서 한 번도 안 들었다는 점이 참 신기하다. 이래서 사람이 하고 싶은 걸 해야 한다는 걸까? 아직 내 길이, 적성이 맞는지 확신은 없어 불안하다가도 주말에도 하루 종일 시간 내서 더 공부해야겠다 생각하고 열심히 강의를 듣는 내 모습에 지금의 선택과 시간을 후에 후회하지는 않겠다는 생각이 들었다.
오늘부터는 오전 9시부터 10시까지 한 시간동안 알고리즘을 푸는 시간을 가진다.
아래는 오늘 날짜에 풀어야했던 알고리즘 문제이다.
/*java*/
class Solution {
public int solution(int angle) {
int answer = 0;
if (0 < angle && angle < 90){
answer = 1;
} else if (angle == 90){
answer = 2;
} else if (90 < angle && angle < 180) {
answer = 3;
} else if(angle == 180){
answer = 4;
} return answer;
}
}
#python
def solution(angle):
if 0 < angle < 90:
return 1 # Acute angle
elif angle == 90:
return 2 # Right angle
elif 90 < angle < 180:
return 3 # Obtuse angle
elif angle == 180:
return 4 # Straight angle
else:
return "Invalid angle"
이후에는 짧게 과제와 주차 관련 발제를 들은 후 개인과제 Level2를 풀었다.
// 0으로 나누기나 잘못된 연산자 기호에 대한 예외 클래스
class CalculatorException extends Exception {
public CalculatorException(String message) {
super(message);
}
}
public class Calculator {
// 연산 결과를 저장하는 컬렉션 타입 필드
private List<Double> results = new ArrayList<>();
// 산술 연산을 수행하고 결과 값을 반환하는 메서드
public double calculate(double num1, double num2, char operator) throws CalculatorException {
double result;
// 연산자 기호에 따라 산술 연산 수행
switch (operator) {
case '+':
result = num1 + num2;
break;
case '-':
result = num1 - num2;
break;
case '*':
result = num1 * num2;
break;
case '/':
// 0으로 나누기 확인
if (num2 == 0) {
throw new CalculatorException("0으로 나눌 수 없습니다.");
}
result = num1 / num2;
break;
default:
// 잘못된 연산자 기호에 대한 예외 처리
throw new CalculatorException("잘못된 연산자 기호입니다.");
}
// 연산 결과를 컬렉션 필드에 저장
results.add(result);
return result;
}
// 연산 결과 컬렉션을 반환하는 게터 메서드
public List<Double> getResults() {
return results;
}
}
public class App {
public static void main(String[] args) {
/* Calculator 인스턴스 생성 */
Calculator calculator = new Calculator();
Scanner sc = new Scanner(System.in);
/* 루프 시작 */
while (true) {
System.out.println("첫 번째 숫자를 입력하세요: ");
double firstNum = sc.nextDouble(); // 보다 정확한 계산을 위해 int 대신 double 사용
System.out.println("두 번째 숫자를 입력하세요: ");
double secondNum = sc.nextDouble();
System.out.print("사칙 연산 기호를 입력하세요 (+, -, *, /): ");
char operator = sc.next().charAt(0);
try {
// Calculator 클래스를 사용하여 계산 수행
double result = calculator.calculate(firstNum, secondNum, operator);
System.out.println("결과: " + result);
} catch (CalculatorException e) {
// 계산 중 발생할 수 있는 CalculatorException 처리
System.out.println("오류: " + e.getMessage());
}
// 스캐너 버퍼 비우기
sc.nextLine();
System.out.println("더 계산하시겠습니까? (종료하려면 'exit'을 입력하세요)");
String text = sc.nextLine();
if (text.equals("exit")) {
break;
}
} /* 루프 종료 */
sc.close(); // 사용이 끝난 스캐너 닫기
}
}
public class Calculator {
/* 연산 결과를 저장하는 컬렉션 타입 필드를 외부에서 직접 접근 하지 못하도록 수정*/
private List<Double> results = new ArrayList<>();
// 산술 연산을 수행하고 결과 값을 반환하는 메서드
...
// 연산 결과 컬렉션을 간접적으로 가져오는 Getter 메서드
public List<Double> getResults() {
return new ArrayList<>(results); // 직접적인 수정을 방지하기 위해 결과의 복사본을 반환
}
// 연산 결과 컬렉션을 간접적으로 수정하는 Setter 메서드
public void setResults(List<Double> newResults) {
results = new ArrayList<>(newResults); // 직접적인 수정을 방지하기 위해 새로운 리스트로 결과를 대체
}
}
/*App class*/
System.out.println("첫 번째 저장된 데이터를 삭제하시겠습니까? (삭제하려면 'yes'를 입력하세요)");
String deleteOption = sc.nextLine();
if (deleteOption.equals("yes")) {
// 연산 결과 중 첫 번째 저장된 데이터 삭제 전에 저장된 결과 출력
System.out.println("삭제 전 저장된 값: " + calculator.getResults());
// 연산 결과 중 첫 번째 저장된 데이터 삭제
calculator.deleteFirstResult();
System.out.println("첫 번째 저장된 데이터가 삭제되었습니다.");
// 연산 결과 중 첫 번째 저장된 데이터 삭제 후의 결과 출력
System.out.println("삭제 후 저장된 값: " + calculator.getResults());
}
/*Calculator class*/
// 연산 결과 리스트에서 첫 번째 데이터를 삭제하는 메서드
public void deleteFirstResult() {
if (!results.isEmpty()) {
results.remove(0);
}
}
/*App class*/
System.out.println("저장된 결과를 조회하시겠습니까? (삭제하려면 'yes'를 입력하세요)");
String inquiryOption = sc.nextLine();
if (inquiryOption.equals("yes")) {
// 조회된 결과 출력
List<Double> results = calculator.inquiryResults();
System.out.println("저장된 결과: " + results);
}
/*Calculator class*/
// 연산 결과 리스트를 조회하는 메서드
public List<Double> inquiryResults() {
return new ArrayList<>(results);
}
Level 2의 요구사항 7까지 풀고서 자바 5주차 나머지 강의를 들고 나머지 시간에는 자바의 정석 유튜브 강의를 들었다.
class Car {
Strigng color;
int door;
void dirve() {
System.out.println("dieve~");
}
void stop() {
System.out.println("stop!");
}
}
class FireEngine ectends Car {
voig water() {
System.out.println("water!!");
}
}
FireEngine f = new FireEngine();
Car c = (Car)f; // 조상인 Car타입으로 형변환 가능
FireEnigne f2 = (FireEnigne)c; // 자손인 FirweEinge타입으로 형변환 가능
Ambulance a = (Ambulance)f; // 에러, 상속관계가 아닌 클래스 간의 형변환 불가능
EX 1-1)
public static void main(Strign args[]) {
Car car = null;
FireEngine fe = new FireEngine();
FireEngine fe2 = null;
fe.water();
car = fe; // Car = (Car)fe;에서 형변환이 생략됨
car.water(); // 컴파일에러, Car타입의 참조변수로는 water() 호출 불가
fe2 = (FireEngine)Car; // 조상타입 → 자손타입 형변환
fe2.water();
Car car2 = (Car)fe2; // 자손타입 → 조상타입 형변환
}
FireEngine의 멤버 개수는 5개(color, door, drive, stop, water)
Car의 멤버 개수는 4개(color, door, drive, stop)
⇒ Car 타입으로 형변환을 한 fe는 water() 호출이 불가능 함.
EX 1-2)
public static void main(Strign args[]) {
Car c = new Car();
FireEngine fe = (FireEngine)c; // 형변환 실행시 에러
fe.water(); // 컴파일 오류 없음
}
위와 같이 컴파일 에러는 없지만 형변환 실행시 에러가 발생할 수 있기 때문에 참조변수 현변환은 실제 객체가 무엇인지가 중요함!
void dowork(Car c) { // Car 또는 Car의 모든 자손 가능
// dowork(new Car());, dowork(new FireEngine());, dowork(new Ambulance()); 3문자 모두 가능
//dowork(new FireEngine());은 Car c = new FireEngine(); dowork(c);와 같음
if(c instanceof FireEngine) { // 1. 형변환이 가능한지 확인
FireEnigne fe = (FireEngine)c; // 2. 형변환
fe.water();
...
}
}
FireEngine fe = new FireEngine();
System.out.println(fe instanceof Object); //true
System.out.println(fe instanceof Car); //true
System.out.println(fe instanceof FireEngine); //true
Object obj = (Object)fe; // 가능
Car c = (Car)fe; // 가능
Q. 참조변수의 형변환을 하는 이유는?
A. 참조변수를 변경함으로써 사용할 수 있는 멤버의 갯수를 조절하기 위해
Q. instanceof연산자는 언제 사용?
A. 참조변수를 형변환하기 전에 형변환 가능여부를 확인할 때
다형성
- Tv t = new SmartTv(); [조상 타입 참조 변수로 자손 타입 객체를 다루는 것]
- 참조변수의 형변환 [사용 가능한 멤버 갯수 조절]
- instanceod 연산자 [형변환 가능 여부 확인]
다형성의 장점
1. 다형적 매개변수
2. 하나의 배열로 여러 종류 객체 다루기
class Product {
int price;
int bonusPoint;
}
class Tv extends Product ()
class Computer extends Product ()
class Audio extends Product ()
class Buyer {
int money = 1000;
int bonusPoint = 0;
}
하지만 다형성을 이용하여 작성한다면? 오버로딩이 필요 없음.
추가
아래의 코드는 위쪽에 있는 코드 두 줄을 합쳐 아래의 한 줄 코드로 작성할 수 있다는 것을 보여주는 예시 코드