2017-10-02 6 views
0

나는 자바의 인터페이스와 추상 클래스에 약간의 문제가있다. 내가 가진 인터페이스 같은java 추상 메서드에서 추상 클래스를 반환

public interface IVector <T extends IVector>{ 
    public IVector add(IVector vector); 
    public IVector sub(IVector vector); 
    public double dotProduct(IVector vector); 
    public IVector scalar(double scalar); 
} 

abstract class : 나는 결과를 반환 할 수있는 방법 n 개의 좌표와 벡터의

public abstract class Vector implements IVector{ 
    final ArrayList<Double> coordinates; 

    public Vector(ArrayList<Double> list){ 
     coordinates = list; 
    } 

    public IVector add(Vector v){ 
     ArrayList<Double> newCoordinates = new ArrayList<>(); 
     if (v.coordinates.size() == this.coordinates.size()){ 
     for (int i = 0; i < this.coordinates.size(); i++) { 
      newCoordinates.add(v.coordinates.get(i)+this.coordinates.get(i)); 
     } 
     } 
     else return null; 
     return new IVector(newCoordinates); 
    } 

그것의 단지 또한,? 미래에 하위 클래스 (예 : 2dVector 또는 3dVector)를 사용하고 싶습니까?

+1

왜 원시 형식을 사용합니까? 당신이 아니라면 당신은 이미 당신의 대답을 가지고있을 것입니다. – Tom

+0

[Generics로 객체 서브 클래스 반환하기] 가능한 복제본 (https://stackoverflow.com/questions/3284610/returning-an-objects-subclass-with-generics) – Tom

답변

3

추상 개체를 직접 만들 수 없습니다. 구체적인 클래스가 필요하거나 추상으로 정의 된 필수 메서드를 재정의 할 수 없습니다.

같은 것이 당신이 찾고있는 것일 수 있습니다. 코드에서 public abstract class Vector implements IVector를 사용하여 Raw Types을 소개하고 피해야한다는

public interface IVector<T extends IVector> { 
    public T add(T vector); 

    public T sub(T vector); 

    public double dotProduct(T vector); 

    public T scalar(double scalar); 
} 

public abstract class Vector<T extends Vector> implements IVector<T> { 
    final ArrayList<Double> coordinates; 

    public Vector(ArrayList<Double> list) { 
     coordinates = list; 
    } 

} 

public class AVector extends Vector<AVector> { 
    public AVector(ArrayList<Double> list) { 
     super(list); 
    } 

    @Override 
    public AVector add(AVector v) { 
     ArrayList<Double> newCoordinates = new ArrayList<>(); 
     if (v.coordinates.size() == this.coordinates.size()) { 
      for (int i = 0; i < this.coordinates.size(); i++) { 
       newCoordinates.add(v.coordinates.get(i) + this.coordinates.get(i)); 
      } 
     } else return null; 
     return new AVector(newCoordinates); 
    } 

    @Override 
    public AVector sub(AVector vector) { 
     return null; 
    } 

    @Override 
    public double dotProduct(AVector vector) { 
     return 0; 
    } 

    @Override 
    public AVector scalar(double scalar) { 
     return null; 
    } 

} 

참고. 알림 public abstract class Vector<T extends Vector> implements IVector<T>을 대신 사용했습니다.

add 메서드를 모두 Vector 개체로 일반화하려는 목표를 달성하려는 경우 일부 형식의 팩토리 메서드가 필요합니다.

이와 비슷한 것이 그럴만 한 시도 일 수 있습니다.

public interface IVector<T extends IVector> { 
    public T add(T vector); 

} 

public interface Factory<T> { 
    public T makeNew (ArrayList<Double> coordinates); 
} 

public abstract class Vector<T extends Vector<T> & Factory<T>> implements IVector<T> { 
    final ArrayList<Double> coordinates; 

    public Vector(ArrayList<Double> list) { 
     coordinates = list; 
    } 

    @Override 
    public T add(T v) { 
     if (v.coordinates.size() == this.coordinates.size()) { 
      ArrayList<Double> newCoordinates = new ArrayList<>(); 
      for (int i = 0; i < this.coordinates.size(); i++) { 
       newCoordinates.add(v.coordinates.get(i) + this.coordinates.get(i)); 
      } 
      // Use the passed parameter as a factory. 
      return v.makeNew(coordinates); 
     } 
     return null; 
    } 

} 

public class AVector extends Vector<AVector> implements Factory<AVector> { 
    public AVector(ArrayList<Double> list) { 
     super(list); 
    } 

    @Override 
    public AVector makeNew(ArrayList<Double> coordinates) { 
     return new AVector(coordinates); 
    } 
} 
0

추상 클래스를 인스턴스화 할 수 없으며 인터페이스도 사용할 수 없습니다. Vector의 하위 클래스 또는 IVector 구현을 반환해야합니다.

관련 문제