Problema ao instanciar uma nova classe de dentro dela mesma

Bom dia,

Criei uma classe chamada Puzzle, e dentro dela eu tenho um método chamado getChildren() que cria novas instancias desta mesma classe com uma alteração no atributo board[] das classes que estou instanciando, mas quando faço isso o atributo board[] da minha classe corrente também está sendo alterado.

Porque acontece isso?

O correto não seria essas novas instancias serem criandas deixando minha classe corrente inalterada?

Por favor me ajudem nessa.

Obrigado,
Rodrigo Zampieri Castilho

Segue abaixo minha classe Puzzle e uma classe para Teste:

// Puzzle.java
import java.util.*;

public class Puzzle
{
	// Atributos privados
	private char[] board; 
	private Puzzle parent; 
	private int value; 
	private int pathValue;
	
	// Constantes publicas
	public static final char BLANK = '-'; 
	public static final char RED = 'V'; 
	public static final char WHITE = 'B';
	
	// Construtores
	public Puzzle(String s)
	{
		board = new char[s.length()];
		for (int i = 0; i < board.length; i++)
			board[i] = s.charAt(i);
		parent = null;
	}
	
    	public Puzzle(String s, Puzzle p)
	{
		board = new char[s.length()];
		for (int i = 0; i < board.length; i++)
			board[i] = s.charAt(i);
		parent = p;
	}
	
	// Métodos Privados
	private int getBlank()
	{
		for (int i = 0; i < board.length; i++)
			if (board[i] == BLANK)
				return i;
		return -1;
	}
	
	private char[] getBoardArray()
	{
		return board;
	}
	
	private String getBoardString()
	{
		String r = new String();;
		for (int i = 0; i < board.length; i++)
			r += board[i];
		return r;
	}
	
	private String getBoardString(char[] c)
	{
		String r = new String();
		for (int i = 0; i < c.length; i++)
			r += c[i];
		return r;
	}
	
	// Métodos Publicos
	public Vector getChildren()
	{
		Vector r = new Vector();
		for (int i = 0; i < board.length; i++)
		{
			System.out.println("Before: " + getBoardString());
			if (i != getBlank())
			{
				char[] c = getBoardArray();
				c[getBlank()] = c[i];
				c[i] = BLANK;
				r.add(new Puzzle(getBoardString(c), this));
			}
			System.out.println("After : " + getBoardString());
		}
		return r;
	}
	
	public int getSize()
	{
		return board.length;
	}
	
    	public void show()
	{
		for (int i = 0; i < board.length; i++)
			System.out.print(board[i]);
		System.out.println();
	}
}

// Teste.java
import java.util.*;

public class Teste
{
	public static void main(String args[])
	{
		Puzzle p = new Puzzle("VBBV-BBVV");
		Puzzle c;
		//System.out.print("show(): "); p.show();
		Vector v = new Vector();
		v = p.getChildren();
		/*
		for (int i = 0; i < v.size(); i++)
		{
			c = (Puzzle)v.get(i);
			System.out.print("Children: ");	c.show();
		}
		*/
	}
}

:?

dica cara, edita o seu post e coloca o código dentro de tags

[code]
Seu código
[/code]

Substituindo

Está alterando pq vc está passando pro child a mesma referencia do pai( this ) sendo assim, o novo obj é criado “apontando” para o mesmo obj em memória. E é por isso q qnd vc mexe no filho altera o pai e qnd mexer no pai tb vai alterar o filho.

Mas eu estou passando o pai para o construtor para ele ser jogado no meu atributo parent do tipo Puzzle, para eu saber quem é o pai do filho que estou criando, o primeiro atributo sim é uma String com a variação de board que estou passando para a criação do filho…

Acho que o problema está nesse pedaço do método getChildren():

char[] c = getBoardArray(); c[getBlank()] = c[i]; c[i] = BLANK;

Você está atribuindo a c uma referência ao board da classe corrente e na linha seguinte está alterando o valor desse array (que também altera board).

Acho que é isso

Muitíssimo obrigado, era isso mesmo, nem me liguei que retornando board daquele jeito eu estaria retornando uma referencia do objeto e não uma cópia.

Valeu :smiley:

Quando você cria uma nova classe, todos os seus atributos também serão novos.
Quando você cria uma nova classe, os atributos que não são mudados, são os atributos staticos, porque eles tem escopo de classe, e não de objeto.
Portanto, se vc quiser que uma nova classe filha fique com os mesmos atributos da classe pai, coloque-os staticos. Você também pode passar os atributos para o construtor da nova classe como parametros.