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

클래스와 객체 16 - final 및 Open Challenge 문제 풀기 본문

프로그래밍 언어/자바

클래스와 객체 16 - final 및 Open Challenge 문제 풀기

huenuri 2024. 8. 19. 10:54

클래스와 객체 마지막 단원을 남겨놓고 있다. 오늘 새벽에 이 부분까지 마치고 싶었으나 다른 할일이 많아서 다 하지 못했다. 오늘까지 연습문제까지 모두 학습하는 건 무리인 것 같고 내일 새벽까지 해서 마치는 걸로 해볼 것이다.

final 키워드는 3군데에서 사용된다. 이들에 대해 각각 알아보자.


 

 

 

1. final 클래스

final이 클래스 이름 앞에 사용되면 클래스를 상속받을 수 없음을 지정한다. 다음 코드에서 FinalClass를 상속받아 SubClass를 만들 수 없다.

final class FinalClass {	// 이 클래스는 상속 불가
	....
}

class SubClass extends FinalClass {	// 컴파일 오류 발생. FinalClas 상속 불가
	....
}

 

 

 

 

2. final 메소드

final로 메소드를 선언하면 오버라이딩 할 수 없는 메소드임을 선언한다. 자식 클래스가 부모 클래스의 특정 메소드를 오버라이딩하지 못하게 하고 무조건 상속받아 사용하도록 한다면 다음과 같이 fninal로 지정하면 된다.

public class SuperClass {
	protected final int finalMethod() { ... }	// finalMethod()는 자식이 오버라이딩 불가
}

class SubClass extends SuperClass {		// SubClass가 SuperClass 상속
	protected int finalMethod() { ... }	// 컴파일 오류. finalMethod() 오버라이딩 안 됨
}

 

 

 

3. final 필드

final로 필드를 선언하면 필드는 상수가 된다.

public class FinalFieldClass {
	final int ROWS = 10;		// 상수 선언. 초기값(10) 지정
    void f() {
    	int[] intArray = new int[ROWS];		// 상수 활용
        ROWS = 30;		// 컴파일 오류. final 필드 값은 변경할 수 없음
    }
 }

 

 

상수 필드는 한 번 초기화되면 값을 변경할 수 없다. final 키워드를 public static과 함께 선언하면, 프로그램 전체에서 사용할 수 있는 상수가 된다. π를 모든 클래스에서 공유할 수 있는 상수로 선언하면 다음과 같다.

class SharedClass {
	public static final double PI = 3.14;
}

 

 

SharedClass 내에서는 다음과 같이 그냥 PI로 사용하면 되지만

double area = PI * radius * radius;

 

 

다른 클래스에서는 다음과 같이 사용하면 된다.

double area = SharedClass.PI * radius * radius;

 


 

 

 

 

 

Open Challenge - 끝말 잇기 게임 만들기

n명이 참가하는 끝말잇기 게임을 만들어보자. 처음 단어는 "아버지ㅌ이다. n명의 참가자들은 순서대로 자신의 단어를 입력하면 된다. 끝말잇기에서 끝말이 틀린 경우 게임을 끝내고 게임에서 진 참가자를 화면에 출력한다. 프로그램에서는 시간 지연을 구현하지 않아도 된다. 그렇지만 참가자들이 스스로 시간을 재어보는 것도 좋겠다. 이 문제의 핵심은 여러 개의 객체와 배열 사용을 연습하기 위한 것으로, main()을 포함하는 WordGameApp 클래스와 각 선수를 나타내는 Player 클래스를 작성하고, 실행 중에는 WordGameApp 객체 하나와 선수 숫자만큼의 Player 객체를 생성한다.

 

 

WordGameApp 클래스


 

Player 클래스

 

솔직히 문제가 너무 어려워서 혼자서는 절대로 풀 수 없는 문제였다. 책 예제를 참고하며 작성하는데만도 1시간이 훌쩍 넘게 걸렸다. 이제 이 코드를 한번 분석해보려고 한다.

 

 

 

클래스 설명

  1. WordGameApp 클래스
    • 필드
      • Scanner sc: 사용자 입력을 받기 위한 Scanner 객체입이다.
      • String startWord: 게임이 시작될 때 사용할 첫 단어로, 초기값은 "아버지"이다.
      • Player[] players: 참가자들을 저장할 Player 객체 배열이다.
    • 생성자
      • WordGameApp(): Scanner 객체를 초기화한다.
    • 메서드
      • createPlayers():
        • 게임에 참가할 인원 수를 입력받고, 각 참가자의 이름을 받아 Player 객체를 생성하여 players 배열에 저장한다.
      • run():
        • 게임을 실행하는 메서드이다. 시작 단어를 출력하고, 게임이 종료될 때까지 참가자들이 순서대로 단어를 입력받고, 끝말잇기 규칙을 체크한다. 규칙을 어긴 참가자는 패배한다.
    • main 메서드
      • main(String[] args): WordGameApp 객체를 생성하고 run() 메서드를 호출하여 게임을 시작한다.
  2. Player 클래스
    • 필드
      • Scanner sc: 참가자가 입력한 단어를 받기 위한 Scanner 객체이다.
      • String name: 참가자의 이름을 저장한다.
      • String word: 참가자가 입력한 단어를 저장한다.
    • 생성자
      • Player(String name): 참가자의 이름을 받아 name 필드를 초기화하고, Scanner 객체를 초기화한다.
    • 메서드
      • getName(): 참가자의 이름을 반환한다.
      • getWordFromUser(): 참가자가 단어를 입력하도록 요청하고, 입력된 단어를 반환한다.
      • checkSuccess(String lastWord):
        • 주어진 lastWord의 마지막 문자와 참가자가 입력한 단어의 첫 문자가 일치하는지 검사한다. 일치하면 true, 그렇지 않으면 false를 반환한다.

 

 

코드 분석 및 동작 설명

  1. 게임 시작
    • WordGameApp 클래스의 main 메서드에서 WordGameApp 객체가 생성되고 run() 메서드가 호출된다. 이 메서드는 게임을 시작하며, 첫 단어는 "아버지"로 시작한다.
  2. 참가자 설정
    • createPlayers() 메서드가 호출되어 게임에 참여할 인원 수와 각 참가자의 이름을 입력받아 Player 객체를 생성하고 배열에 저장한다.
  3. 게임 진행
    • run() 메서드에서 무한 루프가 실행되어, 각 참가자는 순서대로 단어를 입력한다. 입력된 단어가 끝말잇기 규칙에 맞는지 확인하고, 규칙을 지키지 못한 참가자는 패배하며 게임이 종료된다.
    • 참가자의 순서는 next++로 증가하며, next %= players.length로 참가자의 수를 초과하지 않도록 순환한다.
  4. 게임 종료
    • 끝말잇기 규칙을 지키지 못한 참가자가 발생하면 게임이 종료되고, 해당 참가자의 이름과 함께 패배 메시지가 출력된다.

 

 

코드 수정하기

Scanner를 두 클래스에서 중복으로 받고 있어서 이 부분을 수정해주었다.

 

 

 

 

이렇게 끝말잇기를 할 참가자를 몇 명인지 입력하고 참가자들의 이름도 쓴다. 그런 다음 시작하는 단어부터 끝말잇기를 하는데 끝말을 잇지 못하는 사람이 지는 것이다.


 

 

 

 

학습을 마치고

이렇게 아침 1, 2교시 수업에 final부터 도전 문제까지 모두 풀어보았다. 이로써 4장 학습을 모두 마쳤다. 아직도 해야 할 일들이 많이 남아있다. 이론편과 실습편 연습문제가 남아있는데 이제부터 풀어보려고 한다. 오늘 오후에도 머신러닝 수업이라 이 시간에 난 따로 공부를 하면 될 것 같다.

오늘 안에는 반드시 다 풀 수 있을 거라 기대한다.