2015-05-15 2 views
1

редактирования: УстановкаТипа с общим классом

Существует парсер, что вызов метода из ProgramFactory, эта фабрика использует выражения, оператор, тип и программу, как показана в заголовке для реализации ниже. ProgramFactory реализует IProgramFactory, который является интерфейсом, который выглядит следующим образом public interface IProgramFactory<E, S, T, P>

Проблема у меня, кажется, есть то, что выражение является также общим, и я не знаю, как получить это право в реализации (в заголовке и в методах)

это похоже на работу, когда только тип возвращаемого значения типа выражения, как показано здесь

@Override 
public Expression<Boolean> createTrue(SourceLocation sourceLocation) { 
    True expr = new True(); 
    return expr; 
} 

, но не тогда, когда переменная также типа Expression

Я сделал это так, что маски для возвращаемого типа и для типа аргумента у не должны быть такими же

public abstract class BinaryExpression<T, R> extends Expression<T>{ 
    Expression<R> left; 
    Expression<R> right; 
} 

В реализации интерфейса я, кажется, имеют те же проблемы снова и снова.

Expression is a raw type. References to generic type Expression<T> should be parameterized 

Проблема заключается в том, когда я параметризировать эти выражения они говорят мне, что интерфейс не имеет этот метод.

The method createAddition(Expression<Double>, Expression<Double>, SourceLocation) of type ProgramFactory must override or 
implement a supertype method 

это то, что реализация выглядит

@Override 
public Expression<Double> createAddition(Expression left, Expression right, SourceLocation sourceLocation) { 
    Addition expr = new Addition(left, right); 
    return expr; 
} 

это то, что интерфейс выглядит

/** An expression that evaluates to the sum of the given expressions */ 
E createAddition(E left, E right, SourceLocation sourceLocation); 

это то, что добавление класса выглядит

public class Addition extends BinaryExpression<Double, Double>{ 
    public Addition(Expression<Double> left, Expression<Double> right){ 
     this.left = left; 
     this.right= right; 
    } 

    @Override 
    public Double eval() { 
     Double sum = left.eval() + right.eval(); 
     return sum; 
    } 
} 

Это то, что класс Expression выглядит

public abstract class Expression<T> { 
    public abstract T eval(); 
} 

Это то, что заголовок для реализации выглядит

public class ProgramFactory implements IProgramFactory<Expression<?>, Statement, Type, Program>{ 
+1

Есть важные биты отсутствует, декларацию интерфейса и класса первых два фрагментов ('ProgramFactory' и класс реализации) – biziclop

ответ

0

Ваш класс выражение хотел бы ниже,

class Expression<T> { 
    .... 
} 

Ваш интерфейс должен выглядеть следующим образом:

@Override 
public Expression<?> createAddition(Expression<?> left, Expression<?> right, SourceLocation sourceLocation) { 
    Addition expr = new Addition(left, right); 
    return expr; 
} 

А также сделать свой класс выражения общим. создайте ваш

Он решит вашу проблему.

+1

Вы пытались скомпилировать это решение? – biziclop

+0

Да, а также я уже использовал эту структуру в своем приложении. –

+1

Это странно, потому что 'Expression ' определенно не перейдет в 'Expresssion ', поэтому эта строка 'Addition expr = new Addition (left, right);' не должна компилироваться. – biziclop

1

Вы не обеспечили полную реализацию интерфейса.Так что я могу думать, что это что-то вроде:

class MyImplementation implements Interface<Expression> { 
     @Override 
     public Expression<Double> createAddition(Expression left, Expression right, SourceLocation sourceLocation) { 
      Addition expr = new Addition(left, right); 
      return expr; 
     } 
} 

Но должно быть, как:

class MyImplementation implements Interface<Expression<Double>> { 
     @Override 
     public Expression<Double> createAddition(Expression<Double> left, Expression<Double> right, SourceLocation sourceLocation) { 
      Addition expr = new Addition(left, right); 
      return expr; 
     } 
} 

Это сырье типа Expression = |Expression<E>|. И используя простой Expression в параметрах вашего метода, вы удаляете параметр типа. Вы не можете объявить в своей реализации интерфейса raw Expression и переопределить метод, используя параметры с параметром типа (CTE). Подумайте о параметрах типа, таких как простой псевдоним.

+0

. Проблема в том, что выражение является общим и реализация использует несколько типов выражений, поэтому я не могу put Expression как аргумент после интерфейса – Goatherder95

+0

@ Goatherder95 Вы должны действительно описать, что такое настройка и чего вы пытаетесь достичь, поскольку это очень похоже на проблему [XY] (http://meta.stackexchange.com/ вопросы/66377/что-это-The-ху-проблема). – biziclop

+0

Если это так, и вам действительно нужна такая реализация, вы можете объявить 'Interface >' и использовать 'public Expression createAddition (Expression left, Expression right, SourceLocation sourceLocation)' также вы можете связать его как ' 'или' '. Но помните, вы также должны изменить его в объявлении типа класса. –

0

Если вы явно параметризировать все аргументы в интерфейсе:

public interface IProgramFactory<T> { 
    public Expression<T> createAddition(
     Expression<T> left, 
     Expression<T> right, 
     SourceLocation sourceLocation 
); 
} 

Тогда вы можете сделать:

public class ProgramFactory implements IProgramFactory<Double>{ 
    @Override 
    public Expression<Double> createAddition(
     Expression<Double> left, 
     Expression<Double> right, 
     SourceLocation sourceLocation 
){ 
    Expression<Double> expr = new Addition(left, right); 
    return expr; 
    } 
} 
Смежные вопросы