简体   繁体   中英

java return abstract class in abstract method

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?

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);
    }
}

An abstract class cannot be instantiated: nor can an interface. You have to return either a subclass of Vector or an implementation of IVector .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM