I'm coding a simple currency exchange app. I have parent class Currency
which contains the method convertTo
and 3 subclasses which represents some specific currencies. What I want to do is to make that convertTo
method universal so I can invoke it on the subclass and return an object of another subclass.
My best idea is to use generics but while creating a method which should return generic type I encountered an error which says I couldn't initialize raw type directly. The question is how can I initialize this type in parent class method? Please note I did not provide the whole code, some methods are skipped
public class Currency implements CurrencyUnit {
private CurrencyName name;
private BigDecimal amount;
private BigDecimal rate;
private BigDecimal spread;
public Currency() {}
public Currency(BigDecimal amount) {
if(BigDecimal.ZERO.compareTo(amount) > 0) {
throw new IllegalArgumentException("Amount can't be negative.");
}
this.amount = amount.setScale(SCALE, ROUNDING_MODE);
}
//method that should return subclass object
//currencyToConvert is Enum type
public Currency convertTo(CurrencyName currencyToConvert) throws IOException {
if (currencyToConvert.equals(this.getCurrencyName())) {
throw new IllegalArgumentException("Can't convert to same currency.");
}
String currencyUrl = "https://api.exchangeratesapi.io/latest%s%s";
String baseCurrencyUrl = String.format(currencyUrl, "?base=", this.getCurrencyName().toString());
RatesAPI ratesAPI = new RatesAPI(baseCurrencyUrl);
return new Currency(this.amount.multiply(ratesAPI.rateFromAPI(currencyToConvert.toString())));
}
}
//example of subclass (the other subclass for Dollar is basically the same only with currency name difference)
public class Euro extends Currency implements CurrencyUnit {
private final CurrencyName eur = CurrencyName.EUR;
public Euro() {}
public Euro(BigDecimal amount) {
super(amount);
}
public Euro(BigDecimal amount, BigDecimal rate, BigDecimal spread) {
super(amount, rate, spread);
}
@Override
public CurrencyName getCurrencyName() {
return eur;
}
//and the example of Main method
public class Main {
public static void main(String[] args) throws IOException {
Currency eur = new Euro(BigDecimal.ONE);
Currency usd = new Dollar(BigDecimal.ONE);
System.out.println(eur);
usd = eur.convertTo(CurrencyName.USD);
System.out.println(usd);
What I want to achieve is to invoke convertTo
method on Euro
class object so that method return e.g. Dollar class object. As I mentioned before the most elegant solutions for me seems to use generic types. When I created class Currency<T>
and invoked method on e.g Dollar
and as a method parameter, I used Currency<T>
object I encountered exception created "Can't convert to same currency" which seems logical.
I'm not looking for a direct answer to my question, just some guidance because those generics are quite complicated to me.
I tried to search for the answer in web, in fact, I found this but it shows how to return object on which the method was invoked.