관리 메뉴

클라이언트/ 서버/ 엔지니어 "게임 개발자"를 향한 매일의 공부일지

클래스와 객체 18 - 단원 연습문제 이론편 문제 풀기 : 6~8번 본문

프로그래밍 언어/자바

클래스와 객체 18 - 단원 연습문제 이론편 문제 풀기 : 6~8번

huenuri 2024. 8. 19. 17:24

이제 6번부터 문제를 풀어보려고 한다. 바로 이어서 시작해 보겠다.


 

 

 

 

연습문제 이론 편 문제 풀기

 

6번 문제

 

이 코드에 대한 문제를 풀어볼 것이다. 먼저 코드를 분석해 보면 다음과 같다.

 

클래스 분석

  1. 필드 (Fields):
    • private int size;
      • TV의 크기를 나타내는 필드이다. 기본적으로 private 접근 제어자가 붙어있어 외부 클래스에서 직접 접근할 수 없다.
    • private String manufacturer;
      • TV의 제조사를 나타내는 필드
  2. 생성자 (Constructors):
    • 역할: 객체가 생성될 때 기본 크기와 제조사를 설정
    • 설정된 값:
      • size = 32: 기본 크기를 32인치로 설정
      • manufacturer = "LG": 기본 제조사를 "LG"로 설정
    • 출력: 생성된 TV의 크기와 제조사를 콘솔에 출력
    2) 제조사만 받는 생성자 (Constructor with Manufacturer)
    • 역할: 크기는 기본값(32인치)으로 설정하고, 제조사만 사용자 입력을 받는다.
    • 매개변수:
      • manufacturer: 사용자가 입력한 제조사 이름
    • 설정된 값:
      • size = 32: 기본 크기 32인치를 설정
      • manufacturer = manufacturer: 입력받은 제조사를 설정
    • 출력: 생성된 TV의 크기와 입력받은 제조사를 콘솔에 출력
    3) 크기와 제조사를 모두 받는 생성자 (Constructor with Size and Manufacturer)
    • 역할: 사용자가 입력한 크기와 제조사를 모두 설정
    • 매개변수:
      • size: 사용자가 입력한 TV의 크기
      • manufacturer: 사용자가 입력한 제조사 이름
    • 설정된 값:
      • this.size = size: 입력받은 크기를 설정
      • this.manufacturer = manufacturer: 입력받은 제조사를 설정
    • 출력: 설정된 TV의 크기와 제조사를 콘솔에 출력

 

 

(1) this()를 이용하여 생성자를 수정하라.

 

this를 사용해 생성자를 수정했는데 뭔가 틀린 것 같다. 다시 풀어보자! 왜 틀렸을까! this()를 사용하여 생성자를 호출할 때는 반드시 첫 번째 줄에서 호출해야 한다. 그리고 동일한 생성자를 재귀적으로 호출하는 것도 잘못된 방식이다.

 

 

두 번째 수정 코드

 

이렇게 this()를 사용해서 생성자를 수정했는데 print 구문을 제거하면 훨씬 더 간결한 코드가 된다. 그 이유는 다음과 같다.

 

System.out.println을 제거하는 이유

  1. 중복 제거:
    • 원래 코드에서는 각 생성자마다 System.out.println을 사용하여 TV의 크기와 제조사를 출력하고 있었다. 하지만 이는 반복적인 코드로, 동일한 내용의 출력이 각 생성자에 중복되어 있다.
  2. 단일 책임 원칙 (Single Responsibility Principle):
    • 객체 초기화와 관련된 로직을 TV(int size, String manufacturer) 생성자에 집중시켜, 다른 생성자들이 이 생성자를 호출하도록 한다. 이를 통해 코드를 더 간결하고 유지보수하기 쉽게 만든다.
    • 이제 출력은 한 곳에서만 이루어지므로 코드의 책임이 명확해진다. 만약 출력 형식을 변경해야 할 경우, 한 곳에서만 변경하면 된다.
  3. 코드 간결성:
    • 다른 생성자에서 System.out.println을 제거함으로써, 불필요한 코드가 사라져서 더 간결하고 읽기 쉬운 코드가 된다.

 

그럼 이 print 구문을 빼고 다시 코드를 작성해 보겠다.


 

 

 

최종 수정하기

 

철자를 잘못 쓴 부분도 고쳐보았다. 하지만 여전히 필드에는 노란 줄이 뜨고 있다. 이건 getter와 setter로 써야 하는 부분이므로 우선 (1)번 문제는 여기서 마무리하려고 한다.

이 문제 하나 푸는데 거의 1시간쯤 걸린 것 같다.


 

 

 

 

(2) new TV();와 new TV("삼성");을 실행했을 때 어떤 결과가 나오는가?

new TV();는 기본 설정된 "LG" 제조사와 32인치 크기를 사용하는 TV 객체를 생성하고, new TV("삼성");은 "삼성" 제조사와 32인치 크기를 사용하는 TV 객체를 생성한다. 이 코드의 출력은 main에서 해야 한다.

 

 

 

메인 클래스를 하나 만들어서 실행해 보았는데 왜 여기서 new라는 키워드를 사용하는지 의문이 들었다. new 키워드는 Java에서 객체를 생성할 때 사용됩니다. 객체를 생성한다는 것은 클래스에 정의된 설계도를 바탕으로 메모리에 실제 인스턴스를 만드는 것을 의미한다.

 

new 키워드 사용의 목적

  1. 객체 생성
    • 클래스는 객체를 만들기 위한 설계도이다. 그러나 클래스 자체로는 아무런 데이터나 기능을 담고 있지 않다. 실제로 동작하고 데이터를 담는 인스턴스를 만들기 위해 new 키워드를 사용하여 클래스의 객체를 생성한다.
    • 예를 들어, new TV();는 TV 클래스의 객체를 만들고, 이 객체의 필드와 메서드를 사용할 수 있게 한다.
  2. 생성자 호출
    • new 키워드를 사용하면 해당 클래스의 생성자가 호출된다. 생성자는 객체가 생성될 때 자동으로 실행되는 특별한 메서드로, 객체의 초기 상태를 설정하는 데 사용된다.
    • 예를 들어, new TV("삼성");은 "삼성"이라는 값을 인자로 받아 TV 클래스의 해당 생성자를 호출하여, 크기 32인치와 제조사 "삼성"을 가진 TV 객체를 초기한다.
  3. 메모리 할당
    • new 키워드는 JVM에서 객체를 저장할 메모리를 동적으로 할당한다. 이렇게 할당된 메모리에는 생성된 객체의 데이터(예: size, manufacturer)와 객체를 관리하기 위한 정보가 저장된다.

 

정리하면

  • new 키워드는 객체를 생성하고, 생성자를 호출하며, 메모리를 할당하는 역할을 한다.
  • new TV();나 new TV("삼성");과 같은 코드는 TV 클래스의 객체를 만들고, 해당 객체의 생성자를 통해 초기화 작업을 수행하면서 출력 작업도 같이 이뤄지게 된다.

 

 

 

 

(3) 65인치 "삼성" TV 객체를 생성하는 코드를 적어라.

 

 

 

 

이렇게 코드를 만들어보았는데 뭔가 오류가 많이 뜨고 있다. 아마도 객체를 생성하는 방법이 잘못되어 있는 것 같다.

 

  • 정적 팩토리 메서드 createSamsungTV()를 사용해 65인치 삼성 TV를 생성한다. 이 메서드는 65인치와 "삼성"을 인자로 하여 TV 객체를 반환한다.
  • TVMain 클래스에서 TV.createSamsungTV()를 호출해 65인치 삼성 TV 객체를 생성하고 사용할 수 있다.

 

 

객체를 생성할 때 매개변수에 초기값을 줄 수 있다.


 

 

(4) this()를 이용하는 장점

 

1. 코드 중복 제거

  • 생성자에서 공통된 초기화 로직을 반복해서 작성할 필요 없이, 하나의 생성자에서만 초기화 코드를 작성하고 다른 생성자들이 그 생성자를 호출하게 할 수 있다. 이를 통해 코드의 중복을 줄일 수 있다.

2. 일관성 유지

  • 여러 생성자가 동일한 초기화 로직을 사용해야 할 때, this()를 사용하면 모든 생성자가 일관되게 동작하도록 보장할 수 있습니다. 모든 생성자가 동일한 기본 로직을 공유하게 되므로, 초기화 과정에서의 실수를 줄일 수 있다.

3. 유지보수 용이

  • 생성자에서 공통된 초기화 로직이 변경될 경우, 모든 생성자를 수정하는 대신 하나의 생성자만 수정하면 된다. 이는 코드 유지보수를 더 용이하게 만든다.

4. 명확한 객체 초기화

  • 복잡한 객체 초기화가 필요할 때, 기본 값을 설정한 후에 추가적인 값을 설정하는 등의 로직을 명확하게 구조화할 수 있다. 이를 통해 객체가 일관된 상태로 초기화되도록 할 수 있다.

5. 디폴트 값 설정

  • 여러 생성자에서 기본값을 설정하거나 공통된 초기화 과정을 공유할 때 유용하다. 기본 생성자에서 초기화 로직을 작성하고, 다른 생성자들은 그 기본 생성자를 호출하여 기본값을 설정한 후 추가적인 작업만 수행하면 된다.

 

한 문제를 푸는데 이렇게도 많은 개념과 실습이 필요했다. 너무 오랫동안 한 문제를 고민했더니 많이 지친다. 마지막으로 코드를 수정해 본다.

 

최종 수정한 코드

 

 

getter를 통해 필드의 값을 저장하도록 했고, 출력문을 넣어 사용한 객체에 대한 정보를 출력할 수 있도록 만들었다.

 

 

이렇게 하나의 문제를 통해 굉장히 많은 것들을 배울 수 있었다. 


 

 

 

 

7번 문제

컴파일 오류를 지적하고 오류를 수정할 수 있는 방법 모두 제시하라. 그중 객체 지향 프로그래밍에 적합한 방법을 설명하기

 


 

 

 

 

첫 번째 방법 : 필드를 public으로 변경

접근지정자를 public으로 변경하여 Example 클래스에서 이 코드를 이용할 수 있도록 한다.

 

 

 

이 방법은 별로 권장하지 않는 방법이다.


 

 

 

 

두 번째 방법 : public 접근자 메서드 추가

 

 

가장 일반적인 방법은 Person 클래스에 필드에 접근할 수 있는 공개 접근자 메서드(게터와 세터)를 추가하는 것이다. 이렇게 하면 외부 클래스에서도 Person 객체의 필드 값을 읽고 수정할 수 있다.


 

 

 

 

세 번째 방법 : 필드를 protected로 변경

protected 접근 제어자는 같은 패키지 내의 클래스와 상속받은 클래스에서 필드에 접근할 수 있도록 허용한다. 그러나 이 경우, PersonEx 클래스가 같은 패키지 내에 있으므로 접근할 수 있다. 하지만 protected 필드는 패키지 외부의 서브클래스에서도 접근이 가능하므로 주의가 필요하다.

 

 

 

이 중에서 객체 지향 프로그래밍에 가장 적합한 방법은 두 번째이다.


 

 

 

 

문제 8번

다음 코드를 객체 지향 프로그래밍 관점에서 바람직한 코드로 수정하라.

 

 

 

(1) 생성자를 이용하여 수정하라.

 

생성자를 사용해 코드를 수정해 보았다. 변수의 값을 받고 있으므로 기본 생성자보다는 매개변수가 있는 생성자가 더 적합할 것이다. 그러고 나서 값을 초기화시켜야 한다. 그렇지 않으면 오류가 뜬다.

그리고 robot 변수를 사용하기 위해 print 문에서 이 값을 사용하도록 만들었다.


 

 

 

(3) 생성자 대신 메서드를 추가하여 수정하기

 

 

 

 

이렇게 생성자 대신 메소드를 추가하여 수정해 보았다.


 

 

 

학습을 마치고

이 3문제를 푸는데 정말 오래 걸리기도 하고 많이 어려웠다. 이론 문제가 16번까지 있지만 오늘 안에 다 풀 수 있을지 의문이다. 실습문제까지 다 풀려면 며칠 더 걸릴 것 같다.

그래도 지금처럼 천천히 한 문제 한 문제 생각하면서 풀어보려고 한다.