Reputation: 43
I got some problem with java's interfaces and abstract classes. I have interface
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);
}
and abstract class
like this:
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);
}
Its just addition of vectors with n coordinates, how can i return result? I wanna use child classes (like 2dVector or 3dVector) in future?
Upvotes: 0
Views: 1809
Reputation: 7368
An abstract class cannot be instantiated: nor can an interface. You have to return either a subclass of Vector
or an implementation of IVector
.
Upvotes: 0
Reputation: 65813
You cannot create an abstract object directly - you need concrete class or override the required methods defined by the abstract.
Something like this may be what you are looking for.
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;
}
}
Note that using public abstract class Vector implements IVector
in your code introduces Raw Types
and should be avoided. Notice I have used public abstract class Vector<T extends Vector> implements IVector<T>
instead.
To achieve your aim of making the add
method generic to all Vector
objects as you seem to be trying to do you need some form of factory method.
Something like this may be a fair attempt at that.
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);
}
}
Upvotes: 4