【问题标题】:Private Instance variable in an abstract class抽象类中的私有实例变量
【发布时间】:2016-05-31 00:14:44
【问题描述】:

我有一个名为 Tea 的抽象类。该抽象类包含一个名为 size 的实例变量和一个具体方法 getPrice。现在,当我扩展这个抽象类时,大小的值没有保存到变量中,这就是问题的原因。

我错过了什么规则,为什么不能将 size 的值保存到实例变量中?

这是我的代码:

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();    

}

茶类

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;
    }

}

抹茶类

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);
    }

}

冬瓜类

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();
    }   

}

水晶.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;
    }

}

珍珠类

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;
    }
}

这个程序是一个非常简单的 Milktea 系统,它将输入客户订购的茶。茶可以有一个免费的坠子,顾客可以添加他/她想要的坠子。然后系统将写入订单和价格。

除了我上面的问题,你能告诉我我是否成功地以最 OOP 的方式编写了这个程序吗?如果没有,我做错了什么?

【问题讨论】:

标签: java oop


【解决方案1】:

每个子类都有自己的size 定义,隐藏了基类'size。你不应该在每个类中定义size,只在基类中。提供一个返回 size 的访问器(约定为Tea#getSize()),以便所有子类都可以访问它。

你的子类应该像这样调用超类的构造函数:

public Matcha(Size size){
    super(size);
}

【讨论】:

    猜你喜欢
    • 2019-02-10
    • 2018-08-19
    • 2012-04-10
    • 2021-01-28
    • 2018-12-05
    • 1970-01-01
    • 2014-12-27
    • 2012-02-08
    • 1970-01-01
    相关资源
    最近更新 更多