abstract 클래스
public abstract class CardPlayer implements CardPlayerBehavior {
private Card[] hand; // 갖고 있는 카드
private int card_count; // 갖고 있는 카드의 장 수
/** Constructor CardPlayer - max_cards 카드를 수용가능한 Card 배열 객체를 만들어 CardPlayer 생성
* @param max_cards - 들고 있을 수 있는 카드의 최대 장수 */
public CardPlayer(int max_cards) {
hand = new Card[max_cards];
card_count = 0;
}
/** wantsACard - 카드 한 장을 받겠는지 답한다.
* @return 카드를 받고 싶으면 true, 아니면 false */
public abstract boolean wantsACard();
/** receiveCard - 카드를 한장 받는다. 한도(배열 hand의 크기)를 초과하면 받을 수 없다.
* @param c - 카드
* @return 성공적으로 받았으면 true, 그렇지 않으면 false */
public boolean receiveCard(Card c) {
if (card_count < hand.length) {
hand[card_count] = c;
card_count += 1;
return true;
}
else
return false;
}
/** showCards - 들고 있는 카드를 내준다.
* @return 들고 있는 카드 전체 */
public Card[] showCards() {
Card[] card = new Card[card_count];
for (int i = 0; i < card_count; i++)
card[i] = hand[i];
return card;
}
}
abstract 클래스는 위와 같이 구현할 수 있다.
abstract 클래스란,
자바에서는 하나 이상의 추상 메소드 (abstract 메소드)를 포함하는 클래스를 가리켜 추상 클래스(abstract class)라고 한다.
즉, abstract 클래스는 일반적인 클래스에서
abstract 메소드가 하나이상 존재하는 클래스를 의미한다.
그럼, abstract 메소드는 멀까?
abstract 메소드란,
추상 메소드(abstract method)란 자식 클래스에서 반드시 오버라이딩해야만 사용할 수 있는 메소드를 의미한다.
오버라이딩이란? 자바에서 오버라이딩은 부모클래스로부터 상속받은 메소드를 재정의하는 것을 말한다.
정리해서, abstract 메소드는 abstract 클래스를 상속받는 자식클래스에서 abstract 메소드에 대해서 재정의를 한다.
그리고나서, abstract 메소드를 호출한다.
그렇기에, abstract 클래스에선 abstract 메소드를 선언만 해두고,
이를 상속받아서 사용하는 자식클래스에서 abstract 메소드를 생성한 후 해당 클래스에서 상속받아진 abstract 클래스를 호출해서 사용한다.
abstract 메소드를 선언해두는 이유
자바에서 abstract 메소드를 선언하여 사용하는 목적은 abstract 메소드가 포함된 클래스를 상속받는 자식 클래스가 반드시
abstract 메소드를 구현하도록 하기 위함입니다.
예를 들면 모듈처럼 중복되는 부분이나 공통적인 부분은 미리 다 만들어진 것을 사용하고
(이는, abstract 메소드로 정의되지않은 일반적인 메소드를 의미)
이를 받아 사용하는 쪽에서는 자신에게 필요한 부분만을 재정의하여 사용함으로써 생산성이 향상되고 배포 등이 쉬워지기 때문이다.
정리해서, abstract 메소드는 필수적으로 구현되는 사항은 아니지만, 선택적으로 구현이 필요할 때 abstract 메소드로 구현해두고
상속받은 클래스에서 필요하면 메소드를 재정의하여 코드의 관리 및 유지보수를 쉽게 도와준다.
고정적인 메소드로 정의해두는 게 아니라, 필요에 따라 메소드를 커스텀마이징해서 상속받은 클래스에서 사용할 수 있도록 돕는 메소드가
abstract 메소드인 셈이다.
Interface
public interface CardPlayerBehavior {
/** wantsACard - 카드 한 장을 받겠는지 답한다.
* @return 카드를 받고 싶으면 true, 아니면 false */
public boolean wantsACard();
/** receiveCard - 카드를 한장 받는다. 한도(배열 hand의 크기)를 초과하면 받을 수 없다.
* @param c - 카드
* @return 성공적으로 받았으면 true, 그렇지 않으면 false */
public boolean receiveCard(Card c);
}
Interface는 위와 같이 구현할 수 있다.
Interface 란,
인터페이스는 자바에서객체의 사용 방법을 정의해둔 타입이다. (선언만 해두고, 독립적인 개발을 가능케함.)
인터페이스는 자바의 다형성을 극대화하여 개발코드 수정을 줄이고 프로그램 유지보수성을 높이기 위해 인터페이스를 사용한다.
인터페이스는 abstract 클래스와 비슷한 면모를 가지지만, 원칙적으로는 다르다.
이에 대해선 더 말해보자면,
인터페이스는 abstract 메소드만을 내부에 선언해둔다. 그렇기에, 작동이 되는 일반적인 메소드는 구현하지 않는다.
(이는 인터페이스 개발 규칙임)
반면에, abstract 클래스는 abstract 메소드 + 일반적인 메소드를 구현해둔다.
정리해서, Interface는 abstract 메소드만을 구현하고,
abstract 클래스는 abstract 메소드를 하나이상 구현하고, 일반적인 메소드까지 함께 구현한 클래스를 의미한다.
그리고, 인터페이스 & abstract 클래스에 대해선 이번 블랙잭 과제를 직접해보면서,
자세하게 정리해서 재포스팅을 하도록 하겠다.
Interface를 사용하는 이유
- 설계 단계에 인터페이스를 만들어 두면 설계 단계의 산출물과 개발 단계의 산출물을 효율적으로 관리할 수 있다.
- 개발자의 역량에 따른 메소드, 매개 변수 네이밍 차이를 줄일 수 있다.
- 인터페이스는 하나의 객체가 아니라 여러 객체들과 사용이 가능하다. 그렇기에, 개발 코드의 변경없이 어떤 객체를 사용하느냐에 따라 실행내용과 리턴값을 다양화 할 수 있는 장점이 있다.
- 정리해서, 인터페이스는 협업 개발을 위한 "명세서"이자, 개발 전략과 규칙들을 기입해둔 것이라고 생각하면 된다.
(인터페이스를 통해 아직 구현되지 않은 객체의 메소드들을 가져다가 임의로 리턴값을 받아서 종속성이 존재하는 클래스 관계를 해소하여 이에 대한 클래스를 독립적인 개발을 진행할 수 있다. -> 따라서, 협업 개발의 핵심 역할을 배분해서 개발을 진행할 수 있다~)
상속
public class HumanPlayer extends CardPlayer {
public HumanPlayer(int max_cards) {
super(max_cards);
}
public boolean wantsACard() {
String response = JOptionPane.showInputDialog("한장 더 드릴까요? (Y/N)");
return response.equals("Y");
}
}
상속은 위와 같이 구현할 수 있다.
상속이란,
상속은 부모 클래스와 자식 클래스가 있으며, 자식클래스는 부모클래스를 선택해서, 그 부모의 멤버를 상속받아 그대로 쓰는 걸 의미한다.
상속을 사용하는 이유
이미 마련되어 있던 클래스를 재사용해서 만들 수 있기 때문에 효율적이고, 개발 시간을 줄여준다.
즉, 상속을 토대로 클래스 객체를 생성할 필요없이, 상속받는 행위로 부모 클래스에서 구현된 Public 메소드들을 사용할 수 있게되어진다고 생각하면 된다.
정리해서, 상속은 자바에서 정의한 클래스 코드를 재활용하기 위한 개발 전략이자, 규칙인 셈이다.
이를 이용해서 개발에 사용되는 코드 작성비용을 줄일 수 있고, 이에 따라 개발 시간을 단축시킬 수 있다.
마치며
오늘 정리한 개념은 프로그램 설계 방법론에서 대략적으로만 이해했었고,
사실, 이해가 안된 부분이 대다수였는데
막상 처음부터 차근차근 정리하다보니 오늘 정리한 개념들에 대해서 깊이있게 이해할 수 있게 되었다.
그래서, 이를 이용해 코드로 작성해보는 "블랙잭" 과제를 해보려고한다.
이에 대해선 추가 포스팅을 통해서 오늘 정리한 개념을 활용했던 것에 대해서 정리하도록 하겠다.
오늘 포스팅을 하면서 느꼈던 점은 뭐든지 시작해보지 않고선, 그 어려움이 얼마나 어려운지를 감안할 수 없다는 점이다.
그렇기에, 시작도 해보지않고, 어렵다고 상상만 하지말고, 일단 해보면서 그 어려움이 어떤 어려움인지를 직접느껴보면서
이 어려움은 차근차근 처음부터 정리하면 충분히 해처나올 수 있다는 사실을 깨달았다.
그래서, 앞으로 많은 일들과 해처나가야할 일들이 존재할 것이지만, 난 해보지않고서 무서워하기 보단,
일단 해보면서 이 어려움들이 어떤 어려움인지 느낄 것이다. 그러고, 이 어려움을 해처나가기 위해 난, 열심히 그리고 열심히 노력할 것이다.
오늘은 여기까지 포스팅을 하고 마치도록 하겠다.
내가 하고자 했던 일들이 책임감있게 끝나는 "그날까지" 열심히 그리고 열심히
Pre-스타트업 톤 화이팅 !
NestJS 백엔드 개발 화이팅 !!
관상 MBTI 앱 개발 화이팅 !!!
'CS 대학강의' 카테고리의 다른 글
[CS 1-2 | 프로그램 설계 방법론] Java GUI로 슬라이드 퍼즐게임 제작 13주차 (0) | 2022.11.11 |
---|---|
[CS 1-2 | 대학생을 위한 실용금융] 신용관리 10주차 (0) | 2022.11.09 |
[CS 1-2 | 시스템 프로그래밍 기초] 함수 포인터 & 포인터 배열 14주차 (0) | 2022.11.08 |
[CS 1-2 | 시스템 프로그래밍 기초] 배열 포인터 13주차 (0) | 2022.11.04 |
[CS 1-2 | 프로그램 설계 방법론] Java GUI 12주차 (0) | 2022.11.03 |