通用接口或通用子类

问题描述 投票:0回答:2

我正在开发一个符合我需求的线性代数库。目前我有2个想法,但我想知道这两个结构的优点和缺点是做出好的选择。

例如使用向量:

//First structure (simple inheritance using generics 
//to prevent instanceof and casting in subclasses
public abstract class AbstractVector<T>{
    public abstract T method(T t){...}
    ...
}

public class Vector2 extends AbstractVector<Vector2>{
    public Vector2(){...}
    //Implements AbstractVector method, generic T is Vector2
    public Vector2 method(Vector2 vector){...}
}

public class Vector3 extends AbstractVector<Vector3>{...}

public class Vector4 extends AbstractVector<Vector4>{...}



//Second structure (using the structure of java AbstractList/List/ArrayList
//prevents instanceof and casting in subclasses )
public interface Vector<T>{
    T method(T t){...}
}

public abstract class AbstractVector<T> implements Vector<T>{...}

public class Vector2 extends AbstractVector<Vector2>{
    public Vector2(){...}
    //Implements Vector interface method, generic T is Vector2
    public Vector2 method(Vector2 vector){...}
}

public class Vector3 extends AbstractVector<Vector3>{...}

public class Vector4 extends AbstractVector<Vector4>{...}

在使用方面:

//1st structure 
Vector2 vector2 = new Vector2();
Vector3 vector3 = new Vector3();
vector2.method(vector3) //Compile time error!

//2nd structure (I use Vector type main advantage of interface)
Vector vector2 = new Vector2();
Vector vector3 = new Vector3();
vector2.method(vector3) //Runtime error!

现在我有以下优点和缺点:

  1. 对于第一个结构: 优点:简单的继承和编译时错误
  2. 对于第二种结构: 优点:此结构插入通用类型Vector 缺点:只有运行时错误

我是否缺少使一个结构超过另一个结构的优点/缺点?

编辑:该库的主要目的是将其用于几何定义和openGL渲染。

java inheritance interface
2个回答
1
投票

拥有Set界面和单独的实现类HashSetTreeSet的原因是天才。它使所有代码尽可能通用,并使继承变得简单。它允许在将来扩展API,具有向后兼容性(对于其他类)。

而且还有一个Set有一个特殊功能的问题:扩展SortedSetSet界面,只有TreeSet实现。

interface Vector {
}

class SparseVector implements Vector {
}

class UnitVector implements Vector {
}

interface IonicalVector extends Vector {
    IonicalVector rotate(double phi);
}

class QuatrionsVector implements IonicalVector {
    @Override
    public IonicalVector rotate(double phi) { ... }
}

缺点是在LinkedListget(int index)不适合它的开销。

我个人会继续简单的课程,当不同的实现是可以想到的,看看有什么意义。

请注意,您还可以使用builder pattern通过动态选择(私有)实现来实现一个接口。有点像Arrays.asList

Vector v = Vector.with().dim(4).quatrionic(true).build();

1
投票

我理解你的意图。您希望使向量的维度成为编译时常量,并让编译器在维度适合时检入操作(如加法,标量乘法)。我过去曾经想过这些事情,但我无法找到一个好的解决方案。类型可以通过其他类型进行参数化,但不能通过数字进行参数化。

我的建议是摆脱类型定义中的所有数字。只需用字段Vector定义一个类dimension。然后,您可以检查每个操作的维度兼容性,只获得一个类(而不是n个不同的类)。这对于测试和维护代码来说是一个巨大的好处。缺点是维度问题导致运行时异常而不是编译问题。但是拥有清晰整洁的代码比这更重要。

© www.soinside.com 2019 - 2024. All rights reserved.