Java:是否有可能从超类中排除某些内容

时间:2018-01-31 17:50:36

标签: java inheritance

我正在处理一个处理类继承的任务,并且除了字符串格式方法之外,已经完成所有工作并正常工作。程序的输出应如下所示:

Base Salary Plus Commissioned Employee: Sue Smith with ssn: 222-22-2222
Gross Sales: $3000.00 
Commission Rate: 0.05 
with Base Salary:$300.00 
Earnings: $450.00

但它是这样打印的:

Base Salary Plus Commissioned Employee: Sue Smith with ssn: 222-22-2222
Gross Sales: $3000.00 
Commission Rate: 0.05 
Earnings: $450.00
with Base Salary:$300.00 
Earnings: $450.00

问题是在输出中,“收入:450.00美元”在“基本工资:300.00美元”之前打印。课程 BasePlusCommissionEmployee 从课程 CommissionEmployee 扩展而来。每个类都有自己的 toString 方法,BasePlusCommissionEmployee会调用super.toString(),我相信这会导致问题。

我需要能够从CommissionEmployee继承该类,但不要将“收益”带到最后(如图所示)。

这是CommissionEmployee类中toString的代码:

    @Override
    public String toString() {                                    
        return String.format("%s: %s%n%s: $%.2f \n%s: %.2f \n%s $%.2f",    
         "Commissioned Employee", super.toString(),              
         "Gross Sales", getGrossSales(),                       
         "Commission Rate", getCommissionRate(), 
         "Earnings:", earnings());             
   }  

这是BasePlusCommissionEmployee类中的toString的代码(从CommissionEmployee扩展):

    @Override
    public String toString() {                                            
        return String.format("\n%s %s \n%s:$%,.2f \n%s $%.2f",                       
            "Base Salary Plus", super.toString(),                            
            "with Base Salary", getBaseSalary(),
            "Earnings:",earnings());                             
   }  

这是在main中运行的测试代码:

CommissionEmployee employee1 = new CommissionEmployee("Fred", "Jones", "111-11-1111", 2000.0, .05);
BasePlusCommissionEmployee employee2 = new BasePlusCommissionEmployee("Sue", "Smith", "222-22-2222", 3000.0, .05, 300);
System.out.printf("%s%s%s%s%s", employee1, employee2, employee3, employee4, employee5);

非常感谢所有帮助!谢谢!

3 个答案:

答案 0 :(得分:4)

几乎这个确切的问题在Martin Fowler的书Refactoring的第一章中解决了“分解和重新分配陈述方法”部分。 toString()方法可以在基类中按如下方式分解:

    @Override
    public String toString() {
        return getReportHeader() 
                + getReportBase() 
                + getReportSpecifics() 
                + getReportFooter();
    }

    protected String getReportHeader() {
        return String.format("%s: %s",
                             "Commissioned Employee", super.toString());
    }

    protected String getReportBase() {
        return String.format("\n%s %s \n%s:$%,.2f",
                             "Gross Sales", getGrossSales(),
                             "Commission Rate", getCommissionRate());
    }

    protected String getReportSpecifics() {
        return "";
    }

    protected String getReportFooter() {
        return String.format("\n%s $%.2f", "Earnings:", earnings());
    }

然后可以在子类中重写所需的部分:

    @Override
    protected String getReportSpecifics() {
        return String.format("\n%s %s \n%s:$%,.2f",
                             "Base Salary Plus", getBaseSalaryPlus(),
                             "with Base Salary", getBaseSalary());
    }

我建议阅读整本书。它的价格很多倍。

答案 1 :(得分:0)

我们将存储需要在Map中打印的所有键值对。为此,我们将使用一个调整的LinkedHashMap(以防止在重复的情况下插入顺序 - 例如Earnings:)。

class TweakedHashMap<K,V> extends LinkedHashMap<K,V> {

    @Override
    public V put(K key, V value) {
        super.remove(key);
        return super.put(key, value);
    }

}

现在,请使用

中的以下方法
class CommissionEmployee{

    ...
    ...

    public Map<Object,Object> getToStringMap(){
        Map<Object,Object> map = new TweakedHashMap<>();
        map.put("Commissioned Employee",super.toString());
        map.put("Gross Sales",getGrossSales());
        map.put("Commission Rate",getCommissionRate());
        map.put("Earnings:",earnings());
        returun map;
    }
    @Override
    public String toString() {
        return getToStringMap().entrySet().stream().map(e -> e.getKey()+ " : " + e.getValue()).collect(
            Collectors.joining(",\n"));
    }
}


class BasePlusCommissionEmployee extends CommissionEmployee{

    ...
    ...

    @Override
    public Map<Object,Object> getToStringMap(){
        Map<Object,Object> superMap = super.getToStringMap();
        map.put("Base Salary Plus Commissioned Employee",superMap.get("Commissioned Employee"));
        map.put("with Base Salary",getBaseSalary());
        map.put("Earnings:",earnings());
        returun map;
    }

    @Override
    public String toString() {
        return getToStringMap().entrySet().stream().map(e -> e.getKey()+ " : " + e.getValue()).collect(
            Collectors.joining(",\n"));
    }
}

以下是输出:

Base Salary Plus Commissioned Employee: Sue Smith with ssn: 222-22-2222,
Gross Sales: $3000.00,
Commission Rate: 0.05,
with Base Salary:$300.00,
Earnings: $450.00

答案 2 :(得分:0)

您需要在子类中重新定义toString行为而不调用super.toString()

这将使您可以自由选择要显示的字段和顺序。但最大的缺点是它重复了我觉得不值得的代码(因为你还需要处理从CommissionEmployee的父类打印数据)。