< 현재 구현해야할 목록 >
이 부분에서는 Money를 나타내기 위한 단 하나의 클래스만을 가지게 될 것이다. 두 times()의 구현이 거의 비슷하기는 하지만 아직 완전히 동일하지는 않다.
둘을 살펴봐도 동일하게 만들기 위한 방법이 생각나지 않는다. 따라서 이전에서 한 작업을 다시 되돌려 보자
// Franc
public class Franc extends Money{
private String currency;
Money times(int multiplier) {
return new Franc(amount * multiplier, currency);
}
Franc(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
// Dollar
public class Dollar extends Money {
private String currency;
Money times(int multiplier) {
return new Dollar( amount * multiplier, currency);
}
Dollar(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
바꾸고보니 Franc을 반환할지 Money를 반환할지가 중요한 문제인가?
때로는 고민보다 코드를 작성해서 컴퓨터에게 물어보는 것이 빠르다.
// Money
abstract class Money {
protected int amount;
protected String currency;
public String toString() {
return amount + " " + currency
}
Money times(int multiplier) {
return null;
}
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && getClass().equals(money.getClass());
}
Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
static Money dollar(int amount) {
return new Dollar(amount, "USD");
}
static Money franc(int amount) {
return new Franc(amount, "CHF");
}
}
// Franc
public class Franc extends Money{
private String currency;
Money times(int multiplier) {
return new Franc(amount * multiplier, currency);
}
Franc(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
이렇게 작성하면 에러가 뜬다.
이유는 equals() 구현에 있다. equals()는 클래스가 아니라 currency를 비교해야 한다.
// Money
class Money {
protected int amount;
protected String currency;
public String toString() {
return amount + " " + currency;
}
Money times(int multiplier) {
return null;
}
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && currency().equals(money.currency());
}
Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
static Money dollar(int amount) {
return new Dollar(amount, "USD");
}
static Money franc(int amount) {
return new Franc(amount, "CHF");
}
}
// Franc
public class Franc extends Money{
private String currency;
Money times(int multiplier) {
return new Money(amount * multiplier, currency);
}
Franc(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
// Dollar
public class Dollar extends Money {
private String currency;
Money times(int multiplier) {
return new Money(amount * multiplier, currency);
}
Dollar(int amount, String currency) {
super(amount, currency);
}
@Override
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount;
}
}
이제 두 구현이 동일해졌으니 상위 클래스로 끌어 올릴 수 있다.
class Money {
protected int amount;
protected String currency;
public String toString() {
return amount + " " + currency;
}
Money times(int multiplier) {
return new Money(amount * multiplier, currency);
}
String currency() {
return currency;
}
public boolean equals(Object object) {
Money money = (Money) object;
return amount == money.amount && currency().equals(money.currency());
}
Money(int amount, String currency) {
this.amount = amount;
this.currency = currency;
}
static Money dollar(int amount) {
return new Dollar(amount, "USD");
}
static Money franc(int amount) {
return new Franc(amount, "CHF");
}
}
< 현재 구현해야할 목록 >
우리는 지금까지