Bonjour à tous, j'ai un petit problème concernant la généricité et l'héritage. J'ai trois classes :

- VectorPrimal
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
package math;
 
public abstract class VectorPrimal {
 
}
- Vector2f
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
package math;
 
import java.io.Serializable;
import java.util.concurrent.ThreadLocalRandom;
 
/**
 * <b>Vector2f est un vecteur bidimensionnel prenant en argument des rééls </b>
 * 
 *  Cette classe n'est pas <i>immuable</i>, voir IVector2f
 * 
 * @author Xyliaris
 */
 
public class Vector2f extends VectorPrimal implements Serializable
{
	public Vector2f(){}
	public Vector2f( float x, float y )
	{
		this.x = x;
		this.y = y;
	}
 
	public Vector2f(Vector2f vector) 
	{
		this.x 			= vector.x();
		this.y 			= vector.y();
	}
 
	public float x() 								{return this.x;}
	public float y() 								{return this.y;}
 
	public void setX(float x) 						{this.x = x;}
	public void setY(float y) 						{this.y = y;}
	public void addX(float x) 						{this.x += x;}
	public void addY(float y) 						{this.y += y;}
	public void subX(float x) 						{this.x -= x;}
	public void subY(float y) 						{this.y -= y;}
	public void mulX(float x) 						{this.x *= x;}
	public void mulY(float y) 						{this.y *= y;}
	public void divX(float x) 						{this.x /= x;}
	public void divY(float y) 						{this.y /= y;}
 
	public void setValues( float x, float y )		{this.x = x; this.y = y;}	
	public void set( Vector2f value )				{this.x = value.x(); this.y = value.y();}
 
	public float bigger()							{return this.x > this.y ? this.x : this.y;}
	public float smaller()							{return this.x > this.y ? this.y : this.x;}
	public float sum()								{return this.x + this.y;}
 
	public boolean biggerthan( Vector2f vector )	{return ( this.x > vector.x() && this.y > vector.y() );}
	public boolean smallerthan( Vector2f vector )	{return ( this.x < vector.x() && this.y < vector.y() );}
 
	public boolean morePositiveValueThan( Vector2f vector)	{return this.x + this.y > vector.x() + vector.y();}
	public boolean moreNegativeValueThan( Vector2f vector)	{return this.x + this.y < vector.x() + vector.y();}
 
	public boolean awayfrom( Vector2f vector, float distance )	 
	{
		return Math.sqrt(Math.pow(this.x - vector.x(), 2) + Math.pow(this.y - vector.y(), 2)) > distance;
	}
 
	public float normalize( Vector2f vector )		{return (float) Math.sqrt(Math.pow(vector.x(), 2) + Math.pow(vector.y(), 2));}
 
	/**
     * Retourne un vecteur d'angle défini par la position actuel vers une position donné
     * 
     * @see Vector2f#norme()
     */
	public Vector2f shoot( Vector2f endpos )		
	{
		Vector2f shoot = new Vector2f(endpos.x() - this.x, endpos.y() - this.y );
		float norme = this.normalize(shoot);
		shoot.divide(norme);
		return shoot;
	}
 
	public Vector2f randValueBetween( Vector2f value ) 
	{
		if( value.x() <= this.x  && value.y() <= this.y )
			return new Vector2f( value.x() + (float)Math.random() * (this.x - value.x()), value.y() + (float)Math.random() * (this.y - value.y()) );
		if( value.x() <= this.x  && value.y() >= this.y )
			return new Vector2f( value.x() + (float)Math.random() * (this.x - value.x()), this.y + (float)Math.random() * (value.x() - this.y) );
		if( value.x() >= this.x  && value.y() <= this.y )
			return new Vector2f( this.x + (float)Math.random() * (value.x() - this.x), value.y() + (float)Math.random() * (this.y - value.y()) );
		return new Vector2f( this.x + (float)Math.random() * (value.x() - this.x), this.y + (float)Math.random() * (value.y() - this.y) );
	}
 
	public float randRange()
	{
		return (float) ThreadLocalRandom.current().nextDouble(this.smaller(), this.bigger());
	}
 
	public Vector2f scaledCopy( float value ) 		{return new Vector2f(this.x * value, this.y * value);}
 
	public void divide( Vector2f value )			{this.x /= value.x(); this.y /= value.y();}
	public void divide( float value )				{this.x /= value; this.y /= value;}
	public void divide( float x, float y )			{this.x /= x; this.y /= y;}
	public void substract( Vector2f value )			{this.x -= value.x(); this.y -= value.y();}
	public void substract( float value )			{this.x -= value; this.y -= value;}
	public void substract( float x, float y )		{this.x -= x; this.y -= y;}
	public void add( Vector2f value )				{this.x += value.x(); this.y += value.y();}
	public void add( float value )					{this.x += value; this.y += value;}
	public void add( float x, float y )				{this.x += x; this.y += y;}
	public void multiply( Vector2f value )			{this.x *= value.x(); this.y *= value.y();}
	public void multiply( float value )				{this.x *= value; this.y *= value;}
	public void multiply( float x, float y )		{this.x *= x; this.y *= y;}
 
	public Vector2f pow( Vector2f v, float p ) 		{return new Vector2f((float)(Math.pow(v.x(), p)), (float) Math.pow(v.y(), p) );}
	public Vector2f pow( Vector2f v, Vector2f p )	{return new Vector2f((float)(Math.pow(v.x(), p.x())), (float) Math.pow(v.y(), p.y()) );}
 
	public String toString()						{return new String( this.x + ":" + this.y );}
 
 
	///////////////////
	////// BUILD //////
	///////////////////
	/*
	 * * Pour plus de clarter et éviter les conflicts avec les methodes non statique,
	 *   les methodes sont accessible via une énumération de celle-ci.
	 *   
	 * @param method Méthodes disponibles : <\br> - add<\br> - substract<\br> - divide<\br> - multiply
	 * @param target Vecteur a affecter 
	 * 
	 */
	public static Vector2f methods( Method method, Vector2f value, Vector2f target )	
	{
		Vector2f vector = new Vector2f(target);
		switch (method)
		{
		case ADD:
			vector.add(value);
			break;
		case SUBSTRACT:
			vector.substract(value);
			break;
		case DIVIDE:
			vector.divide(value);
			break;
		case MULTIPLY:
			vector.multiply(value);
			break;
		default:
			break;
		}
		return vector;
	}
 
	public static Vector2f methods( Method method, float value, Vector2f target )	
	{
		Vector2f vector = new Vector2f(target);
		switch (method)
		{
		case ADD:
			vector.add(value);
			break;
		case SUBSTRACT:
			vector.substract(value);
			break;
		case DIVIDE:
			vector.divide(value);
			break;
		case MULTIPLY:
			vector.multiply(value);
			break;
		default:
			break;
		}
		return vector;
	}
 
	public static float methods( Method method, Vector2f target )	
	{
		switch (method)
		{
		case ADD:
			return target.randRange();
		case BIGGER:
			return target.bigger();
		case SMALLER:
			return target.smaller();
		case RANDRANGE:
			return target.randRange();
		default:
			break;
		}
		return 0f;
	}
 
	private float x;
	private float y;
 
	private static final long serialVersionUID = 8318071254896859350L;
}
-Map2d
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
package math;
 
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
 
 
public class Map2d<K extends VectorPrimal,V>  // All vector type ?
{
	public Map2d(Vector2f size)
	{
		this.objects = new HashMap<Vector2f,V>();
		this.size 	= size;
	}
 
	public boolean add( V value )
	{
		if( this.objects.size() >= this.size.sum() )
			return false;
 
		Vector2f vector = this.bigger();
		if(!this.addNext(vector))
			return false;
 
		this.objects.put(vector, value);
		return true;
	}
 
	public boolean switchPosition( Vector2f first, Vector2f second )
	{
		if( !this.objects.containsKey(first) || !this.objects.containsKey(second))
			return false;
 
		V tfirst = this.objects.get(first);
		this.objects.replace(first, this.objects.get(second));
		this.objects.replace(second,tfirst);
 
		return true;
	}
 
	public boolean replace( V value, Vector2f position )
	{
		if( !this.objects.containsKey(position) )
			return false;
		this.objects.replace(position, value);
		return true;
	}
 
	public V get( Vector2f position )
	{
		if(this.objects.containsKey(position))
			return this.objects.get(position);
		return null;	
	}
 
	public boolean remove( Vector2f position )
	{
		if(this.objects.containsKey(position))
		{
			this.objects.remove(position);
			return true;
		}
		return false;
	}
 
	public void clear()
	{
		this.objects.clear();
	}
 
	private boolean addNext( Vector2f vector )
	{
		if( vector.x() < this.size.x() )
		{
			vector.addX(1); // @cha 182
			return true;
		}
		else if( vector.y() < this.size.y() )
		{
			vector.addY(1); // @cha 182
			vector.setX(0); // @cha 182
			return true;
		}
		return false;
	}
 
	private Vector2f bigger()
	{
		Vector2f bigger = new Vector2f(0f,0f);
		for( Iterator<Map.Entry<Vector2f,V>> iterator = this.objects.entrySet().iterator(); iterator.hasNext(); )
		{
			Map.Entry<Vector2f,V> entry = iterator.next();
			if( entry.getKey().morePositiveValueThan(bigger) )
				bigger = entry.getKey();
		}
		return bigger;
	}
 
	private final Vector2f size;
	private Map<Vector2f,V> objects;
}
La classe Vector2f est une classe qui me sert depuis très longtemps dans mes projets.
Aujourd'hui j'ai décidé de créer une classe Map2d permettant exactement la même chose qu'un tableau 2d avec plus tard d'autres avantages.
Au début j'ai fait cette classe en pensant que le type de valeur pour l'indexage serait uniquement un Vector2f mais comme j'ai des classes Vector2i, Vector2d etc... (uniquement pour les primitifs, pour les objets j'ai la classe Vector2<Type>)
j'ai voulu pouvoir utiliser toutes ces autres classes. Donc j'ai ajouté à ma classe Map2d la possibilité de choisir son type de clé, cependant je dois donc remplacer toutes les variables ayant pour type Vector2f par le type K.
Et c'est là que se pose un problème. Pour pouvoir faire ça je dois utiliser le polymorphisme et donc j'ai créé la classe VectorPrimal (pour les vecteurs avec type primitif donc). Le problème c'est que je ne peux pas connaitre le type de la classe fille par avance, donc j'ai pensé à rendre ma classe VectorPrimal générique mais mes classes filles, elles, ne le sont pas et je ne veux pas qu'elles le deviennent pour plusieurs raisons. Donc voilà je suis bloqué sur ça, pour le moment j'avance avec les méthodes qui me seront utiles pour la classe Map2d en attendant de trouver une solution à mon petit problème.
Merci de votre aide !