2013-06-21 2 views
1

Я определил для своего проекта функциональный интерфейс под названием Function. Она имеет только один метод, call, как это:Создание функционального интерфейса, работающего с разными типами объектов

public interface Function { 
     public void call(); 
    } 

И в моем поле объекта, у меня есть это:

public class Field { 
     private Square[][] matrix; //Square is dispensable. 
     public Field(int rows, int cols) { 
     matrix = new Square[rows][cols]; 
     for(int i = 0; i < rows; i++){ 
      for(int j = 0; j < cols; j++){ 
      this.matrix = new Square(i * Square.NORMAL_WIDTH, j * Square.NORMAL_HEIGHT); 
      } 
     } 
     } 
    } 

Он отлично работает, и это напоминает JavaScript, но пока я не могу пройти объект моего внимания к нему. но учтите, что я хочу, чтобы развивать этот метод:

public void each(Function f){ 
     int rows = matrix.length; 
     for(int i = 0; i < rows; i++){ 
     int cols = matrix[i].length; 
     for(int j = 0; j < cols; j++){ 
      f.call(); 
     } 
     } 
    } 

Это будет придавать определенный кусок кода (в данном случае реализация функции) для каждого элемента матрицы. Таким образом, я могу получить доступ к его свойствам. Но каждый объект матрицы является квадратом. Как я могу получить к нему доступ? Я мог бы передать его функции,

//making an small alteration to the parameter. 
    public interface Function { 
     public void call(Square square); 
    } 

    public void each(Function f){ 
     int rows = matrix.length; 
     for(int i = 0; i < rows; i++){ 
     int cols = matrix[i].length; 
     for(int j = 0; j < cols; j++){ 
      f.call(matrix[i][j]); 
     } 
     } 
    } 

Но все же, я бы в ловушке в Square типа. Может быть, я мог бы использовать общие типы?

+0

... Да, дженерики - вот как вы решаете эту проблему? –

+0

Возможно, вам лучше не пытаться превратить Java в JavaScript. – Raedwald

+0

Угадайте, что вы правы. Но, это полезный интерфейс. Возможно, я использую его в других частях проекта. – thepanuto

ответ

2

Да, вам нужно сделать его общим.

Простейший случай:

public interface Function<T> { 
    public void call(T arg); 
} 

public void each(Function<Square> f) { ... } 

Чем лучше практика, чтобы объявить each() следующим образом:

public void each(Function<? super Square> f) { ... } 

, так что вы можете применить не только Function<Square>, но и Function любого из его надтипа , таких как

Function<Object> PRINT = new Function<Object>() { 
    public void call(Object arg) { 
     System.out.println(arg); 
    } 
} 
+0

Ницца! Спасибо. Я не знал ограничения 'super' в объявлении, только' extends'. На самом деле, ты уверен, что это не то, что ты имел в виду? – thepanuto

0

Вместо

private Square[][] matrix; 

использование

private Function[][] matrix; 

и код не привязан к площади. Конечно, в конечном итоге он будет привязан к конкретному классу, но код менее связан. (И я не уверен, что дженерики помогут там или нет, так как слишком рано утром для меня гораздо труднее думать :-)

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