[英]Generic interface or generic subclass
我正在開發適合我需要的線性代數庫。 目前,我有2個想法,但我想知道這兩種結構的優缺點,是一個不錯的選擇。
例如,vectors:
//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!
目前,我有以下優點和缺點:
Vector
我是否缺少使一個結構勝過另一個結構的優點/缺點?
編輯:此庫的主要目的是將其用於幾何定義和openGL渲染。
我明白你的意圖。 您想使向量的尺寸成為編譯時常量,並讓編譯器在尺寸合適的情況下簽入操作(如加法,標量乘法)。 過去一段時間,我一直在考慮這些事情,但是我找不到一個好的解決方案。 類型可以由其他類型參數化,但不能由數字參數化。
我的建議是擺脫類型定義中的所有數字。 只需定義一個具有Field dimension
的類Vector
。 然后,您可以檢查每個操作的尺寸兼容性,並只獲得一個類(而不是n個不同的類)。 這對於測試和維護代碼有巨大的好處。 缺點是維問題導致運行時異常,而不是編譯問題。 但是擁有清晰,整潔的代碼比這更重要。
具有Set
接口和單獨的實現類HashSet
, TreeSet
很簡單。 它使所有代碼盡可能通用,並使繼承簡單。 它允許將來擴展API,並具有向后兼容性(對於其他類)。
還有一個Set
具有一項特殊功能的問題: SortedSet
接口擴展了Set
並僅由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) { ... }
}
缺點是get(int index)
LinkedList
中的開銷不適合它。
就我個人而言,我將繼續使用簡單的類,並且當可以想到不同的實現時,這才有意義。
請注意,您還可以使用構建器模式通過動態選擇(私有)實現來實現一個接口。 有點像Arrays.asList
。
Vector v = Vector.with().dim(4).quatrionic(true).build();
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.