我最近正在研究Java继承如何工作的层次结构设计。但我不确定我应该从哪个方面开始。
给出计算二进制表达式的示例,它必须使用两个类Literal
和Binary
。但它建议给出以下样本输出:
Literal a = new Literal(6);
Literal b = new Literal(12);
System.out.println(b); //Prints out: 12.0
System.out.println(b.evaluate()); //Prints out: 12.0
Binary e = new Binary(b, a, Operation.DIVIDE);
System.out.println(e); //Prints out: 12.0 / 6.0
Binary f = new Binary(e, a, Operation.PLUS);
System.out.println(f); //Prints out: (12.0 / 6.0) + 6.0
System.out.println(f.evaluate()); //Prints out: 8.0
Binary g = new Binary(e, f, Operation.TIMES);
System.out.println(g.evaluate()); //Prints out: 16.0
* Operation
是一个枚举定义了四个操作PLUS,MINUS,TIMES和DIVIDE
我试图设计一个Literal
类和另一个类Binary
,它从类Literal
扩展而来......但我发现以下关注可能有问题产出的要求......:
Variable v = new Variable(“a“);
Expression n = new Binary(f, v, Operation.DIVIDE);
System.out.println(n); //Prints out: ((12.0 / 6.0) + 6.0) / a
Environment x = new Environment();
x.addVariable(“a“, 4.0); //Variable “a“ has a value 4.0 in x
System.out.println(n.evaluate()); //RuntimeException
System.out.println(n.evaluate(x)); //Prints out: 2.0 (8.0 / 4.0 = 2.0)
我发现课程Binary
必须从Expression
延伸才能满足要求......实际上我的设计在开头是不对的?
答案 0 :(得分:1)
如果您可以将类B
的对象描述为"是类A
的" ,则应考虑继承。然后,课程B
应该扩展课程B
。
另一方面,类之间的直接继承会导致一些讨厌的问题,所以最好通过 interfaces 来表达"是一个" 关系,让类BImpl
成为类A
的属性,它将继承的调用委托给:
interface A{
void someMethod();
}
interface B extends A{
void someOtherMethod();
}
class C implements A {
void someMethod(){}
}
class D implements B {
private A a;
D(A a){
this.a=a;
}
void someMethod(){
a.someMethod()
}
void someOtherMethod(){}
}
答案 1 :(得分:0)
从上次评论中,问题变得清晰:
但变量
类型f
定义为Binary
,并且在构造函数内部可能有Literal
或Binary
如果Literal
和Binary
都延伸Expression
,则构造函数可以使用2 Expression
个参数,这意味着Literal
和Binary
是可以接受的:
interface Expression {...}
class Literal implements Expression {...}
class Binary implements Expression {
...
public Binary(Expression lhs, Expression rhs, Operation op) {
...
}
...
}