Reputation: 1773
I have an abstract class named Tea. That abstract class contains an instance variable named size and a concrete method getPrice. Now when I extend this abstract class, the value of size was not saved to variable which is the cause the problem.
What rule did I miss and why can't it save the value of size to the instance variable?
Here's my code :
package milktea;
import milktea.Drink.TeaDrink;
import milktea.Tea.Size;
public class MilkTea {
/**
* @param args the command line arguments
*/
public static void main(String[] args) {
Tea tea1 = Drink.buyTea(TeaDrink.MATCHA, Size.LARGE);
System.out.println(tea1.getName() + "..." + tea1.getPrice());
Sinker sinker1 = tea1.getFreeSinker();
System.out.println(sinker1.getName() + "..." + sinker1.getPrice());
Tea tea2 = Drink.buyTea(TeaDrink.WINTERMELON, Size.SMALL);
System.out.println(tea2.getName() + "..." + tea2.getPrice());
}
}
Drink.class
package milktea;
import milktea.Tea.Size;
import milktea.sinker.*;
import milktea.teaType.*;
public class Drink {
public enum TeaDrink {
BLACKTEA,
CHRYSANTEMUM,
MATCHA,
OOLONG,
WINTERMELON
}
public enum Sinkers {
CRYSTAL,
PEARL
}
public static Tea buyTea(TeaDrink tea, Size size){
if(tea==TeaDrink.BLACKTEA){
return new BlackTea(size);
}else if(tea==TeaDrink.CHRYSANTEMUM){
return new Chrysantemum(size);
}else if(tea==TeaDrink.MATCHA){
return new Matcha(size);
}else if(tea==TeaDrink.OOLONG){
return new Oolong(size);
}else{
return new Wintermelon(size);
}
}
public static Sinker addSinker(Sinkers sinker){
if(sinker==Sinkers.CRYSTAL){
return new Crystal();
}else{
return new Pearl();
}
}
}
Sinker.class
package milktea;
public interface Sinker {
String getName();
Double getPrice();
}
Tea.class
package milktea;
public abstract class Tea {
public enum Size {
LARGE, MEDIUM, SMALL
}
private Double largeSize;
private Double mediumSize;
private Double smallSize;
private Size size;
public abstract String getName();
public abstract Sinker getFreeSinker();
public Double getPrice(){
System.out.println("LARGE " + this.size);
if(this.size==Size.LARGE){
return largeSize;
}else if(this.size==Size.MEDIUM){
return mediumSize;
}else if(this.size==Size.SMALL){
return smallSize;
}
return 0.0;
}
}
Matcha.class
package milktea.teaType;
import milktea.Sinker;
import milktea.Tea;
import milktea.sinker.Crystal;
public class Matcha extends Tea {
private final Double largeSize = 3.15;
private final Double mediumSize = 2.15;
private final Double smallSize = 1.15;
private final Size size;
public Matcha(Size size){
this.size = size;
}
@Override
public String getName() {
return "Matcha";
}
@Override
public Sinker getFreeSinker() {
return new Crystal(0.0);
}
}
Wintermelon.class
package milktea.teaType;
import milktea.Sinker;
import milktea.Tea;
import milktea.sinker.NoFreeSinker;
public class Wintermelon extends Tea{
private final Double largeSize = 3.15;
private final Double mediumSize = 2.15;
private final Double smallSize = 1.15;
private final Size size;
public Wintermelon(Size size){
this.size = size;
}
@Override
public String getName() {
return "Wintermelon";
}
@Override
public Sinker getFreeSinker() {
return new NoFreeSinker();
}
}
Crystal.java
package milktea.sinker;
import milktea.Sinker;
public class Crystal implements Sinker{
private Double price;
public Crystal(Double price){
this.price = price;
}
public Crystal() {
}
@Override
public String getName() {
return "Crystal";
}
@Override
public Double getPrice() {
return this.price;
}
}
NoFreeSinker.class
package milktea.sinker;
import milktea.Sinker;
public class NoFreeSinker implements Sinker{
@Override
public String getName() {
return "No free sinker.";
}
@Override
public Double getPrice() {
return 0.0;
}
}
Pearl.class
package milktea.sinker;
import milktea.Sinker;
public class Pearl implements Sinker {
private Double price;
public Pearl(Double price){
this.price = price;
}
public Pearl() {
}
@Override
public String getName() {
return "Pearl";
}
@Override
public Double getPrice() {
return this.price;
}
}
This program is a very simple Milktea system, wherein it will type the tea ordered by the customer. A tea can have a free sinker and the customer may add his/her desired sinker. Then the system will write the order and the price.
Aside from my question above, could you tell me if I have successfully coded this program in the most OOP possible?? If not, what did I do wrong?
Upvotes: 1
Views: 112
Reputation: 13999
Each of your subclasses has its own definition of size
, hiding the base class' size
. You shouldn't define size
in each class, just in the base class. Provide an accessor (Tea#getSize()
by convention) which returns size
so that all the subclasses can access it.
Your subclasses should call the superclass' constructor like so:
public Matcha(Size size){
super(size);
}
Upvotes: 3