[Résolu] pb avec ArrayListe

tmtc
[Résolu] pb avec ArrayListe

Bonjour,

j'ai un petti problème.

J'ai une classe abstraite

public abstract class MaForme 

Et des classes qui dérivent de MaForme

 public class MaForme1 extends MaForme

 public class MaForme2 extends MaForme

 public class MaForme3 extends MaForme2

Dans une frame, j'ai défini un ArrayList de type MaForme

ArrayList <MaForme> mf = new ArrayList <MaForme>();

MaForme1 m1 = new MaForme1();
MaForme2 m2 = new MaForme2();
MaForme3 m3 = new MaForme3();

mf.add(m1);
mf.add(m2);
mf.add(m3);

J'ai le message d'erreur suivant pour pour l'instruction mf.add(m1) :

Quote:
The method (MaForme) in the type ArrayList is not applicable for the arguments (MaForme3)

Est ce quelqu'un sait à quoi cela est dû?

K-lo

C'est pas plutot :

ArrayList <MaForme> *mf = new ArrayList <MaForme>();

MaForme1 *m1 = new MaForme1();
MaForme2 *m2 = new MaForme2();
MaForme3 *m3 = new MaForme3();

mf->add(m1);
mf->add(m2);
mf->add(m3);

:?:
Niroken

Hmmm j'ai regardé ton soucis tmtc et avec les informations
que tu as fourni j'ai produit ce code ci :

import java.util.*;

public class ArrayListMain
{
	public static void main(String[] args)
	{
		Maforme1 maforme1 = new Maforme1();
		Maforme2 maforme2 = new Maforme2();
		Maforme3 maforme3 = new Maforme3();
		
		ArrayList <Maforme> arrayList = new ArrayList <Maforme>();
		
		arrayList.add(maforme1);
		arrayList.add(maforme2);
		arrayList.add(maforme3);
	}
}

abstract class Maforme
{
	public abstract void UneMethode();
}

class Maforme1 extends Maforme 
{
	public void UneMethode()
	{
	
	}
}

class Maforme2 extends Maforme
{
	public void UneMethode()
	{
	
	}
}

class Maforme3 extends Maforme2
{

}

et cela marche bien : aucune erreur n' est sortie.

Selon moi, je pense que ca vient de l'implémentation des classes.Si
tu veux que je pousse un peu plus loin l'investigation, va falloir que tu me
montres ton beau code :) , avec l'implémentation des méthodes des
classes.

Bonne chance

fredericmazue

@k-lo

Quote:
C'est pas plutot :
ArrayList *mf = new ArrayList ();

MaForme1 *m1 = new MaForme1();
MaForme2 *m2 = new MaForme2();

Hey man :lol:
On est en Java là. Pas de pointeur avec le langage pour bébé :)

@tmtc
Très vraisemblablement Niroken a raison. Une implémentation d'une méthode déplait au compilateur. Implémentation manquante, signature différente, etc.
Et comme dit encore très justement Niroken, faudrait montrer un peu de ton beau code pour qu'on voit :)

tmtc

j'ai implémenté toutes les méthodes de la classe abstraite dans MaForme1 et MaForme2. Je ne sais pas trop quel est le problème.

Le code de mes classes est assez voire même très long, je ne sais pas si ça le fait de tout mettre car ça va prndre de la place.

fredericmazue

Quote:
Je ne sais pas trop quel est le problème.

Et nous sans infos supplémentaires, on ne risque pas de la savoir....
tmtc

Voilà ma classe abstraite


public abstract class MaForme implements Serializable{

  protected boolean selected = false;
 
    public abstract void dessine(Graphics g) ;
    
    public abstract void tourne (double a);
    
    public abstract boolean appartient (int x, int y);
    
    public abstract int nb();
 	
}

Et la classe MaForme1 avec juste la définition des méthodes de MaForme


public class MaForme1 extends Geometrie implements Serializable{

 private static final long serialVersionUID = 1L;

   public int x;

   public int y;

    public MaForme1(){
    }
 
    public MaForme1(int a, int o){
    	this.x=a;
    	this.y=o;
    }
   
    public int distance(MaForme1 p) {
        int dx = p.x - x ;
        int dy = p.y - y ;
        int res= dx*dx + dy*dy;
        return res ;         
    } 

   public void tourne(double a)
   { 
	 MaForme1 o = new MaForme1(0,0);
     int ox = this.x - o.x ;
     int oy = this.y - o.y ;
     double cosa = Math.cos (a) ;
     double sina = Math.sin (a) ;
     x = (int) (o.x + cosa * ox - sina * oy) ;
     y = (int) (o.y + sina * ox + cosa * oy) ;              
   }

	public void dessine(Graphics g) {
		// TODO Auto-generated method stub
		Graphics2D g2 = (Graphics2D)g;
		
		 if (selected)
	         g2.setColor(Color.green);
	      else
	         g2.setColor(Color.blue);		
    	
        g2.drawRect(x,y,1,1);
	}

	public boolean appartient(int x, int y) {
		MaForme1 p = new MaForme1(x,y);
		if(this.equals(p)){
			return false;
		}
		return true;
	}

	public int nb() {
		
		return 1;
}
}
fredericmazue

Vraiment très simple...

Quote:
public abstract class MaForme
public class MaForme1 extends Geometrie

Le compilateur s'attend à voir:
public class MaForme1 extends MaForme
Sinon il considère que les méthodes de la classe abstraite MaForme ne sont pas implémentées et il a raison.

Quelques remarques en dehors de ce problème particulier:

- tu mets des implements Serializable partout. Ca n'a pas de sens. (Sauf si tu suis le principe de certains qui affirment que mieux vaut un code long et laid qu'un code concis et élégant :lol: )
Bref, à partir du moment où MaForme implémente Serializable, tout ce qui en dérive l'implémente aussi. Donc MaForme implements Serializable est suffisant.

- ensuite:

public void dessine(Graphics g) {
      Graphics2D g2 = (Graphics2D)g; 

Pardonne moi, mais quelle atrocité.
Ca veut dire qu'à chaque fois qu'une forme quelle qu'elle soit se dessine, elle va faire le transtypage dynamique de Graphics vers Graphics2D. Tu te doutes bien qu'un transtypage dynamqiue come celui-ci à un coût élevé à l'exécution. Déjà que Java est un langage qui se traîne, pas la peine de lui mettre des boulets aux pieds.
Comme vraisemblablement tu passes le Graphics depuis la méthode paintComponent d'un panneau, à ce moment déjà tu dois faire le transtypage, donc à ce moment c'est le Graphics2D que tu dois passer aux méthodes dessine, dont la signature doit être redéfinie bien entendu:

public void dessine(Graphics2D g)

Enfin dans un post d'avant j'ai vu qu'une forme, en plus de dériver de la classe abstraite, dérive aussi d'une autre forme.
Je suis assez près à parier que c'est le fameux cercle qui dérive de l'ellipse :)
Un débat moult fois houleux qui a usé des milliers de claviers. :lol: Mais normalement, si le cercle, pour le matheux est un cas particulier de l'ellipse, en POO, il est meilleurs de déclarer une classe Ellipse et une classe Cercle, toutes deux dérivées de MaForme et sans lien entre elles.

tmtc

c'est bien un extends MaForme que j'ai dans mon code, c'est juste une erreue que j'ai faite lors de l'envoi du message

fredericmazue

Tu as du faire la même erreur quelque part dans ton code :lol:
Et cela ne change rien au reste de mon post.

Maintenant comme tu caches ton code, on va pas t'aider plus quand bien même on le voudrait, on ne le peut pas. Et puis franchement:

Quote:
c'est juste une erreue que j'ai faite lors de l'envoi du message

Tu pouvais pas faire un copier/coller au lieu de finasser ? Il y a quelque chose de secret dans ce code, que tu as cru bon d'en montrer un autre différent ? C'est quoi ton but ? Arriver à résoudre ton problème ou bien faire perdre leur temps à ceux qui essaient de t'aider ? Hein ? :twisted:
Niroken

lol je vais faire mon chieur mais....

import java.util.*;
import java.lang.*;
import java.awt.*;
import javax.swing.*;
import java.io.*;
 
public class testing 
{
	public static void main(String[] args)
	{
		MaForme1 maForme1 = new MaForme1();
				
		ArrayList <MaForme> arrayList = new ArrayList <MaForme>();
		
		arrayList.add(maForme1);
	}
}

abstract class MaForme implements Serializable{ 

  protected boolean selected = false; 
  
    public abstract void dessine(Graphics g) ; 
    
    public abstract void tourne (double a); 
    
    public abstract boolean appartient (int x, int y); 
    
    public abstract int nb(); 
     
} 

class MaForme1 extends MaForme implements Serializable{ 

 private static final long serialVersionUID = 1L; 

   public int x; 

   public int y; 

    public MaForme1(){ 
    } 
  
    public MaForme1(int a, int o){ 
       this.x=a; 
       this.y=o; 
    } 
    
    public int distance(MaForme1 p) { 
        int dx = p.x - x ; 
        int dy = p.y - y ; 
        int res= dx*dx + dy*dy; 
        return res ;          
    } 

   public void tourne(double a) 
   { 
    MaForme1 o = new MaForme1(0,0); 
     int ox = this.x - o.x ; 
     int oy = this.y - o.y ; 
     double cosa = Math.cos (a) ; 
     double sina = Math.sin (a) ; 
     x = (int) (o.x + cosa * ox - sina * oy) ; 
     y = (int) (o.y + sina * ox + cosa * oy) ;              
   } 

   public void dessine(Graphics g) { 
      // TODO Auto-generated method stub 
      Graphics2D g2 = (Graphics2D)g; 
       
       if (selected) 
            g2.setColor(Color.green); 
         else 
            g2.setColor(Color.blue);       
        
        g2.drawRect(x,y,1,1); 
   } 

   public boolean appartient(int x, int y) { 
      MaForme1 p = new MaForme1(x,y); 
      if(this.equals(p)){ 
         return false; 
      } 
      return true; 
   } 

   public int nb() { 
       
      return 1; 
} 
}

Pour moi RAS la, ca compile et éxécution nickel :)

Il faut plus de code lol!

fredericmazue

Quote:

lol je vais faire mon chieur mais....

Tu en es bien loin. Surtout après l'aide que tu as apportée.

Quote:
Pour moi RAS la, ca compile et éxécution nickel

Surtout après avoir apporté la correction class MaForme1 extends MaForme ;) :lol:

Quote:
Il faut plus de code lol!

Ouais... et surtout faudrait le code concerné par le problème. Et non pas un "autre" code, hein tmtc ?.... :evil:
Niroken

Et puis quand j'ai dis qu'il fallait faire hériter les nouvelles
classes cercle polygon rectangle etc..ce n'était pas une obligation.

En effet on peut définir soi même dans la classe concerné la
méthode pour définir si un point appartient a la figure ou non.

Dans le cas du cercle si ca peut te simplifier la vie je l'ai implémenté
avec ce brave pythagore:)

import java.awt.*;
import javax.swing.*;
import java.lang.*;

public class MonCercle
{
	int centerX;
	int centerY;
	int rayon;
	
	public static void main(String[] args)
	{
		MonCercle monCercle = new MonCercle(50, 50, 40);
		System.out.println("" + monCercle.AppartientAMonCercle(30, 30));
		System.out.println("" + monCercle.AppartientAMonCercle(0, 100));
	}
	
	public MonCercle(int centerX_arg, int centerY_arg, int rayon_arg)
	{
		centerX = centerX_arg;
		centerY = centerY_arg;
		rayon = rayon_arg;
	}
	
	public void DessineMonCercle(Graphics g)
	{
		g.drawOval(centerX, centerY, rayon, rayon);
	}
	
	public boolean AppartientAMonCercle(int X, int Y)
	{
		boolean result = false;
		
		int distancePointFromCenter = (int) Math.sqrt(((X - centerX) * (X - centerX)) + ((Y - centerY) * (Y - centerY)));

		if (distancePointFromCenter <= rayon)
			result = true;
		
		return result;
	}
}

C'est tout aussi abordable ainsi. bon franchement il n'y a que le polygone
qui soit pénible a réimplémenter soi même.

Bonne chance

fredericmazue

Quote:
Dans le cas du cercle si ca peut te simplifier la vie je l'ai implémenté
avec ce brave pythagore:)

Soit dit en te remerciant à nouveau pour cette contrib et sans vouloir la dévaloriser: avec Pythagore et avec petit bug ;)

int distancePointFromCenter = (int) Math.sqrt(((X - centerX) * (X - centerX)) + ((Y - centerY) * (Y - centerY))); Le calcul de distancePointFromCenter est intrinsèquement un nombre à virgule flottante. Mettons que tu trouves 10.5 En castant en un int il reste 10. Si rayon vaut 10 tu déduis que le point est dans le cercle alors qu'il est dehors en réalité. Tiens ça me donne envie de troller un peu, parce que si je ne veux pas dévaloriser ta contrib, pour Java je ne vais pas me gêner ;) :lol:. J'ai tellement entendu l'ânerie qui dit que Java est un langage sûr parce qu'il est typé statiquement. On voit ce que vaut l'argument dans ce cas. Pour sûr qu'en Haskell ça ne serait pas arrivé ;) Je ne dis pas avec Lisp mais c'est juste histoire de changer. ;) Et puis je ne voudrais pas troubler la sieste de l'homme de Néanderthal dans sa caverne. :lol:

Quote:
bon franchement il n'y a que le polygone
qui soit pénible a réimplémenter soi même.

Surtout le polygone convexe ;)
tmtc

Merci à niroken et fredericmazue pour l'aide et le temps que vous avez accordé à mon problème. Mon code n'a rien de secret, j'ai juste voulu le simplifier en ne montrant que ce qui posait un problème car il est assez long. J'ai recodé ma classe et il n'y a plus de problème. Je ne sais toujours pas quelle était l'erreur mais bon...

fredericmazue

Quote:
j'ai juste voulu le simplifier en ne montrant que ce qui posait un problème

Je sais bien ;)
Quote:
J'ai recodé ma classe et il n'y a plus de problème. Je ne sais toujours pas quelle était l'erreur mais bon...

Tu peux être sûr que l'erreur est dans ce que Niroken ou moi t'avons dit. C'était peut être une simple erreur de frappe bêbête que tu as enlevée sans t'en apercevoir. Tu ne serais pas le premier à qui ça arrive.