Java 接口、抽象类还是其他?

Java 接口、抽象类还是其他?,java,Java,如果我有两个常规和科学类,它们的实现应该是什么样子?也就是说,我的意思是在传统的课堂上会有一些方法,比如:加法、减法、乘法、除法 但在科学课上也会有这些方法,但不同的是,在科学课上会有额外的方法,例如 返回除法的余数等 我有几种变体,但我不知道哪一种最合适: 1) 创建抽象计算器类,该类将包含常用的抽象方法,例如加法、减法、除法、乘法和成员变量,然后常规类和科学类将继承计算器类。此外,传统类将实现自己的附加方法。但是,此解决方案没有意义,因为例如,加法方法在常规类和科学类中具有相同的实现 abs

如果我有两个常规和科学类,它们的实现应该是什么样子?也就是说,我的意思是在传统的课堂上会有一些方法,比如:加法、减法、乘法、除法

但在科学课上也会有这些方法,但不同的是,在科学课上会有额外的方法,例如 返回除法的余数等

我有几种变体,但我不知道哪一种最合适:

1) 创建抽象计算器类,该类将包含常用的抽象方法,例如加法、减法、除法、乘法和成员变量,然后常规类和科学类将继承计算器类。此外,传统类将实现自己的附加方法。但是,此解决方案没有意义,因为例如,加法方法在常规类和科学类中具有相同的实现

abstract class Calculator {

    protected BigDecimal result = BigDecimal.ZERO;
    protected BigDecimal currentNumber;
    protected String chainOfAllNumbers = "";

    abstract public void addition(double number);
    abstract public void subtraction(double number);
    abstract public void multiplication(double number);
    abstract public void division(double number);
}

class Conventional extends Calculator {

    @Override
    public void addition(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.add(currentNumber);
    }  

    @Override
    public void subtraction(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.subtract(currentNumber);   
    }

    @Override
    public void multiplication(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.multiply(currentNumber);   
    }

    @Override
    public void division(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.divide(currentNumber);   
    } 
}

class Scientific extends Calculator {

     @Override
    public void addition(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.add(currentNumber);
    }  

    @Override
    public void subtraction(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.subtract(currentNumber);   
    }

    @Override
    public void multiplication(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.multiply(currentNumber);   
    }

    @Override
    public void division(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.divide(currentNumber);   
    }

    //In addition, implementation of own methods

}
2) 创建抽象类计算器,该计算器将包含常用方法,例如加法、减法、除法、乘法和成员变量,但使用这些方法的实现,因为在这两种情况下,实现(例如加法)是相同的。然后传统和科学将继承计算器类。此外,科学课也有自己的方法。这似乎是一个很好的解决方案,但是一个空的常规类看起来很奇怪,我不知道是否会是这样,这是一个理想的机制吗

abstract class Calculator {

    protected BigDecimal result = BigDecimal.ZERO;
    protected BigDecimal currentNumber;
    protected String chainOfAllNumbers = "";

    public void addition(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.add(currentNumber);
    }  

    public void subtraction(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.subtract(currentNumber);   
    }

    public void multiplication(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.multiply(currentNumber);   
    }

    public void division(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.divide(currentNumber);   
    } 
}

class Conventional extends Calculator {


}

class Scientific extends Calculator {

    //In addition, implementation of own methods

}
3) 使用常规类和科学类实现的通用抽象方法创建接口。然后创建第二个接口,该接口将具有抽象方法,并且只能由Scientific类实现。但这种解决方案没有意义,因为某些方法的实现(例如添加)是相同的

interface Operations {

    abstract public void addition(double number);
    abstract public void subtraction(double number);
    abstract public void multiplication(double number);
    abstract public void division(double number);
}



interface additionalOperations {

    abstract public int mod();
}

或者其他方法肯定会更好?

如果不应该实例化
计算器
类,请将其设置为
抽象类。这是个好决定。但这并不意味着你也必须把它的方法抽象化。因此,方法2)将是最好的方法。但这并不能解决你的另一个问题:

这似乎是一个很好的解决方案,但是一个空的常规类看起来很奇怪,我不知道是否会是这样,这是一个理想的机制吗

abstract class Calculator {

    protected BigDecimal result = BigDecimal.ZERO;
    protected BigDecimal currentNumber;
    protected String chainOfAllNumbers = "";

    public void addition(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.add(currentNumber);
    }  

    public void subtraction(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.subtract(currentNumber);   
    }

    public void multiplication(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.multiply(currentNumber);   
    }

    public void division(double number) {

        currentNumber = BigDecimal.valueOf(number);
        result = result.divide(currentNumber);   
    } 
}

class Conventional extends Calculator {


}

class Scientific extends Calculator {

    //In addition, implementation of own methods

}
如果
传统的
计算器没有什么不同,为什么两者都有呢?将
常规
作为一个常规类,使用前者的所有方法(现在是冗余的)
计算器
类,并在
科学
中扩展
常规

如果你想有一个接口
计算器
,它要求所有不同的计算器至少有这些基本方法,那么制作一个接口并在上面的类中实现它

编辑:这将导致以下总体结构(这是一个建议-当然还有很多其他方法可以做到这一点,特别是因为我不知道这些类/接口将生活在什么样的环境中):


通过这种方式,每种类型的计算器要么直接实现接口
计算器
(如果它想以不同的方式处理事情,那么
常规计算器
),要么它可以扩展
常规计算器
(我想这是更可能的版本).

我认为您对什么是接口和抽象类有一个基本的误解。如果您的科学计算器“是一个”普通计算器+一些附加函数,那么您将编写一个实现,并有两个接口:ConventionalCalc和ScientificCalc,其中ScientificCalc扩展了ConventionalCalc。然后,实现类实现这两个接口。这样一来,你就有了相同的代码,函数的可见性也就绑定到了正在使用的接口上。Fildor,从你的陈述中,我得出结论,我应该创建一个计算器类的实现,以及两个常规和科学的接口。然后,根据需要,我将创建Calulator类的一个对象,并根据需要调用的方法将其分配给Conventional或Scientifical类型的引用变量?我说得对吗?没错。在这种情况下,这将是避免重复代码的最简单方法。我希望有接口,因此从您的声明中我得出结论,我应该创建一个计算器类的实现,以及两个常规和科学接口,这将扩展常规接口。然后Calculator类将实现这两个接口,并且根据需要,我将创建Calculator类的一个对象,并根据调用的方法将其分配给常规或科学类型的引用变量?我说的对吗?不,你错了。让我补充一个解释。。。等一下。。。。
public class ConventionalCalc implements Calculator {

    @Override
    public void addition(double number) {
        // TODO
    }

    @Override
    public void subtraction(double number) {
        // TODO
    }

    @Override
    public void multiplication(double number) {
        // TODO
    }

    @Override
    public void division(double number) {
        // TODO
    }
}
public class ScientificCalc extends ConventionalCalc {

    public void someScientificMethod(double number) {
        // TODO
    }

    public void anotherScientificMethod(double number) {
        // TODO
    }
}