현재 격자 모양의 구조에서 작업을 처리 할 수있는 추상 코드로 작업하고 있습니다. 구체적인 방법 대신 lambda 표현식을 허용하고 그리드 요소 간의 방향성 관계에 기반한 기능을 제공하는 프레임 워크를 개발하려고 시도했습니다. 이러한 메서드에 제네릭 형식을 반환하려고 할 때 문제가 발생했습니다.일반 반환 형식 및 람다 함수 인수
나는 특정 방향의 그리드 요소를 찾는 람다 함수를 허용하는 작업 방법과 각 요소에 대해 특정 방법을 실행하는 소비자를 가지고있다. 대신 요소-찾는 기능이 메소드가 호출 될 때마다 시간을 통과해야하는
public static <E> void forEachClockwise(Direction d, Function<Direction, ? extends E> f, Consumer<? super E> c){
/*For each of the orthogonal directions, in order:*/
c.accept(f.apply(d));
/*end For*/
}
, 나는 그것을 선언과 같은 기능을 갖는 인터페이스 '직교'를 가지고 있고,에 forEachClockwise 방법을 과부하가 좋은 것입니다 결정 이 인터페이스의 요소를 받아들입니다.
public static <O extends Orthogonal> void forEachClockwise(Direction d, O center, Consumer<O> c){
forEachClockwise(d, center::findNextByDirection, c);
}
여기서는 제네릭을 사용했으며 Consumer 메서드가 캐스팅하지 않고 그리드 요소의 필드에 액세스 할 수 있도록 선언했습니다. 직교 인터페이스와 내가 만든 테스트 클래스가 몇 가지 다른 것들을 시도 함에도 불구하고 경고없이 그리고 캐스트없이 컴파일되지 않았기 때문에 이것은 잘못된 설계 선택이었다고 우려하고 있습니다. 내가 해봤 findNextByDirection의
public interface Orthogonal {
public <E extends Orthogonal> E findNextByDirection(Direction a);
}
두 '유효'구현은 다음과 같습니다
/* in Coordinate implements Orthogonal: */
@Override
public <E extends Orthogonal> E findNextByDirection(Direction a) {
return (E) (/*The proper Coordinate*/);
}
그리고
최적@Override
public Coordinate findNextByDirection(Direction a) {
return /*The proper Coordinate*/;
}
//Warning on return type declaration:
/*Type safety: The return type Element for findNextByDirection(Direction) from the type Element needs unchecked conversion to conform to E from the type Orthogonal*/
, 나는 방법을하고 싶은 그 forEachClockwise (그리고 다른 메소드)는 받아 들일 수 있습니다. 이것은 캐스팅하지 않고 호출하는 동일한 클래스의 요소를 리턴합니다. 좌표의 findNextByDirection은 좌표를 반환해야하며 주소는 주소를 반환해야하고 셀은 셀을 반환해야합니다. 기타 질문 및 답변 일반 반환 형식을 사용하여 메서드를 만드는 방법에 대해 알아 보았지만 찾지 못했습니다. 이러한 종류의 메서드를 람다 매개 변수로 사용하는 방법에 대한 힌트.
아직 시도하지 않은 몇 가지 사항은 직사각형으로 정의 된 일부 메서드로 forEachClockwise 메서드를 호출하거나 인수로 직사각형 및 방향의 일부를 받아들이는 새로운 findByDirection 메서드를 만드는 것입니다. 내가 시도한 것처럼. 인터페이스를 고유 한 제네릭 형식으로 지정하는 것이 다른 접근 방식이지만 인터페이스가 "MyClass가 직교를 구현"하는 것으로 모든 직교 클래스를 선언하는 것은 분명히 잘못되었고 목적이 없습니다.
이 인터페이스를 완전히 디자인 했습니까? 제네릭이 무언가를하기를 기대하면서 처음부터 틀렸던가? 아니면 클래스를 가져 와서 올바른 메소드를 호출하고 그 타입의 요소를 일반적으로 반환하는 간단한 방법이 있습니까?
전체 코드 :
package test;
import java.util.function.Consumer;
import java.util.function.Function;
public enum Direction {
NORTH, EAST, SOUTH, WEST;
public static <O extends Orthogonal> void forEachClockwise(Direction d, O center, Consumer<O> c){
forEachClockwise(d, center::findNextByDirection, c);
}
public static <X> void forEachClockwise(Direction d, Function<Direction, ? extends X> f, Consumer<? super X> c){
c.accept(f.apply(d));
forEachExcept(d, f, c);
}
public static <X> void forEachExcept(Direction d, Function<Direction, ? extends X> f, Consumer<? super X> c){
for(int i=0; i<3; i++){
d = Direction.getClockwise(d);
c.accept(f.apply(d));
}
}
public static Direction getClockwise(Direction d){
switch(d){
case EAST:
return SOUTH;
case NORTH:
return EAST;
case SOUTH:
return WEST;
case WEST:
return NORTH;
default:
return null;
}
}
}
interface Orthogonal {
public <E extends Orthogonal> E findNextByDirection(Direction a);
}
class Coordinate implements Orthogonal{
int x;
int y;
public Coordinate(int x, int y){
this.x = x;
this.y = y;
}
public int getX(){
return x;
}
public int getY() {
return y;
}
@Override //Warning on "Coordinate" below. Compiler suggests writing
//entire <E extends Orthogonal> method signature
public Coordinate findNextByDirection(Direction a) {
switch(a){
case NORTH:
return new Coordinate(x+1, y);
case SOUTH:
return new Coordinate(x-1, y);
case EAST:
return new Coordinate(x, y+1);
case WEST:
return new Coordinate(x, y-1);
default:
return null;
}
}
}
(경고와 함께) 컴파일하는 예제 전체를 만들면 도움이 될 것입니다. 예를 들어,이 직교의 구현은 경고없이'public class Element is Orgogonal { @Override public element findNextByDirection (Direction a) { return this; } } ' – assylias
반환 형식 선언에 해당 스 니펫이 경고 메시지와 함께 컴파일되지 않습니다. Element : "형식 안전 : 형식 요소에서 findNextByDirection (Direction)의 반환 형식 요소에 E를 준수하는 검사되지 않은 변환이 필요합니다. Orthogonal 유형 " –
(직교가 아닌 요소를 반환하는) 메소드 서명을 복사 했습니까? – assylias