2016-11-20 3 views
-1

Я недавно изучил иерархический дизайн того, как работает наследование Java. Но я не уверен, в какой момент я должен начать.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, РАЗ и РАЗДЕЛИТЬ

Я попытался создать класс 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

Почему 'Binary' расширяет' Literal'? Я ожидаю, что они оба будут реализовывать «Выражение». –

+0

Синтаксический анализ выражений - идеальный выбор для применения композитного шаблона дизайна: https://sourcemaking.com/design_patterns/composite – aquila

+0

@JornVernee Поскольку переменная 'f' определена с объектом типа' Literal' ... Извините ... Я могу неправильно понять понятия ... – null

ответ

1

Вы должны рассмотреть наследование, если вы можете описать объекты класса B, как «является» класса A. Затем класс B должен расширять класс B.

С другой стороны, прямое наследование между классами может вызвать некоторые неприятные проблемы, так что лучше, чтобы выразить «является» отношения через интерфейсы и имеют класс 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(){} 
} 
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) { 
     ... 
    } 
    ... 
} 
+0

Да, спасибо, что я думаю о последующих требованиях.Но первый этап (верхний блок) имеет только два класса - двоичный и буквенный - в первом требовании ... Класс Expression для второго этапа (нижний блок), поскольку требования разделены на две части ... – null

+0

@null , но никто не сказал, что вы не можете сделать больше ... правильно? –

Смежные вопросы