A mio parere, né né: Entrambi sono n -le tuple con differenti n . Il problema è che la maggior parte dei linguaggi non consente di parametrizzare i tipi con un valore.
Quando decidi una certa ereditarietà, dovresti considerare la moltiplicazione della matrice.
/1 0\ /2\ ? /1 0 0\ /2\
// failure with Vector3 <: Vector2 -- vec.z can be != 0
if (vec instanceof Vector2)
assert vec.z == 0;
// failure with Vector3 <: Vector2 -- vec.z can be != 0
if (vec instanceof Vector2)
assert vec.norm() == sqrt(vec.x^2 + vec.y^2); // euclidean norm - invalid in non-cartesian systems
// failure with Vector2 <: Vector3 if they are mutable (Circle-Ellipse Problem)
if (vec instanceof Vector2) {
vec.z = 42;
assert vec.z == 0;
}
// failures concerning dimensionality with *any* inheritance relation
// when considering matrix multiplication
1/ · |3| = |0 1 0| · /
/ /1 0\ /2\ ? /1 0 0\ /2\
// failure with Vector3 <: Vector2 -- vec.z can be != 0
if (vec instanceof Vector2)
assert vec.z == 0;
// failure with Vector3 <: Vector2 -- vec.z can be != 0
if (vec instanceof Vector2)
assert vec.norm() == sqrt(vec.x^2 + vec.y^2); // euclidean norm - invalid in non-cartesian systems
// failure with Vector2 <: Vector3 if they are mutable (Circle-Ellipse Problem)
if (vec instanceof Vector2) {
vec.z = 42;
assert vec.z == 0;
}
// failures concerning dimensionality with *any* inheritance relation
// when considering matrix multiplication
1/ · |3| = |0 1 0| · /
/ %pre% 0 0/
0 0/
Stai implicitamente sostenendo che una o entrambe le moltiplicazioni funzionano (e dovrebbero eventualmente essere equivalenti). A questo punto ogni matematico sta avendo un attacco di cuore, perché ha violato alcune regole sulla dimensionalità richiesta.
Penso che sia ovvio che Vector3
non può essere un sottotipo di Vector2
, e non il contrario: non puoi generalmente usarne uno al posto dell'altro. Entrambi hanno proprietà comuni . Definirei probabilmente un'interfaccia Vector
con metodi come component(i)
che fornisce il componente i -th (invece di getX
, getY
, ...), size()
che fornisce la dimensionalità e norm()
che calcola la lunghezza.
Se sei deciso ad avere un tipo che eredita da un altro, considera questi casi di test:
%pre%
Ciò significa che devo ammettere a malincuore che avere Vector2 ereditato da Vector3 potrebbe funzionare nella maggior parte dei casi, se sono immutabili e non stai facendo nulla di più di un'aggiunta o una moltiplicazione scalare.
Nota sulle coordinate
Se non vuoi fare algebra vettoriale ma vuoi semplicemente rappresentare le coordinate, allora questa risposta sarebbe diversa, perché le coordinate 2D possono essere viste come una proiezione di coordinate 3D in un piano (o qualsiasi altra superficie parametrizzabile da due numeri). In questo caso, ogni coordinata 2D avrà anche una coordinata 3D, ma le due coordinate provengono da due diversi sistemi di coordinate. La proiezione su z = 0
-plane è un caso molto particolare di ciò in cui è possibile visualizzare la coordinata 2D come una sorta di coordinata 3D. Questo non è generalmente il caso in tutti i sistemi di coordinate 2D.