Relacionamento tem um

18 respostas
denisspitfire

Ae gente, tenho uma duvida a respeito de um objeto conter outro…

Digamos que eu crie uma classe motor sem um construtor.

Depois uma classe que criem objetos motor para se “completar”, no caso uma classe carro.
A classe carro cria um motor para dentro do objeto sem parametro algum, sem um construtor.

E se eu criar um construtor para a classe motor? Não mataria a criação de um carro sem parametro para a classe motor?

public class CarroTeste {

	public static void main(String[] args) {
		Motor motor = new Motor();
		Carro carro = new Carro("uno",220,motor);
		carro.motor.tipo="exemplo";
		System.out.println("A Velocidade máxima do "+carro.nome+" é "+carro.velocidadeMaxima);
		System.out.println(carro.motor.tipo);
	}

}
public class Carro {
	String nome;
	int velocidadeMaxima;
	Motor motor;
	Carro(String nome,int velocidadeMaxima, Motor motor){
		this.nome = nome;
		this.velocidadeMaxima = velocidadeMaxima;
		this.motor = motor;
	}
}
public class Motor {
	String tipo;
}

Tudo isso funciona porque a classe motor nao tem um construtor… agora… digamos que falem
¬ olhe a classe Motor esta ruim! crie um construtor para ela, desse jeito ela esta sem parametro e blah blah blah.
dai eu vou la e crio um construtor… nao atrapalharia em todo o resto da criação?
Qual a solução?
Agradeço desde já

18 Respostas

diego.sas

Não teria problema algum…
A única coisa que mudaria seria na hora de instanciar um motor, o resto ficaria idêntico

marciosouzajunior

Te recomendo o link http://marciosouzajunior.blogspot.com/2010/07/construtores-java.html

denisspitfire

diego.sas:
Não teria problema algum…
A única coisa que mudaria seria na hora de instanciar um motor, o resto ficaria idêntico

ok, vamos lá

public class Motor {
	String tipo;
	Motor(String tipo){
		this.tipo = tipo;
	}
}

criei o construtor, agora ele exige o tipo… só que magicamente, eu “atrapalhei” para nao falar outra coisa, a vida de quem vai usar a classe carro.

Pois na parte

Motor motor = new Motor();

Não funciona mais.

marciosouzajunior

Não sei se você leu o link que te indiquei mas se você sobrecarregar um construtor, o construtor padrão deixará de existir.
Então vocẽ tem duas opções: Cria um construtor padrão para manter a compatibilidade:

public class Motor {  
        String tipo;  
        Motor(String tipo){  
            this.tipo = tipo;  
        }  
        Motor(){
            super();
        }
    }

Ou se não fizer isto, quem instanciar motor deverá passar o tipo pra ele:

Motor motor = new Motor("v8");
diego.sas

denisspitfire:
diego.sas:
Não teria problema algum…
A única coisa que mudaria seria na hora de instanciar um motor, o resto ficaria idêntico

ok, vamos lá

public class Motor {
	String tipo;
	Motor(String tipo){
		this.tipo = tipo;
	}
}

criei o construtor, agora ele exige o tipo… só que magicamente, eu “atrapalhei” para nao falar outra coisa, a vida de quem vai usar a classe carro.

Pois na parte

Motor motor = new Motor();

Não funciona mais.

Como o Márcio mencionou.
Toda classe tem um construtor por default, porém se criar um construtor recebendo parâmetros, terá que sobreescrever o construtor de Object.

denisspitfire

exatamente onde eu quero chegar… se for preciso retirar o construtor padrão como eu fiz… literalmente matar o construtor padrao e deixar somente o que exige parametros.
Agora, outras classes estarao envolvidas com essa classe. Quero saber se existe um plano para isso, pois eu nao posso deixar o padrão ainda funcionando.

Exemplo, tenho 300 classes lá linkadas com a classe motor e nenhuma manda parametro, se um cara simplesmente cria um construtor ele vai acabar com tudo… como evitar isso?

diego.sas

Tem que continuar funcionando do jeito que esta?
Uma classe pode ter quantos construtores for necessário.
Se sim e só declarar o construtor default explicitamente na classe. e caso seja criado outros não afetará nada.
Agora se você não declarar o construtor default, você estará obrigando todos que utilizam sua classe a passar o parametro, e que utiliza o construtor default dará erro.

denisspitfire

disso eu entendi… mas nao teve nenhuma vez que voce precisou matar a default? e ficar sem ela?
tipo… nao tem algo que avise o programador da classe motor para ele nao fazer besteira???
tipo… “OLHA A CLASSE MOTOR NAO PODE FICAR COM PARAMETROS EXISTEM OUTRAS QUE DEPENDEM DELA SEM PARAMETRO”
eu entendi o funcionamento, mas nao acha que alguem poderia criar algo que desencadeasse uma serie de problemas ?

marciosouzajunior

Penso que se o programador sabe que tem 300 objetos utilizando o construtor padrão e ele vai lá e muda o construtor sem manter a compatibilidade pode bater a carta de aviso do mesmo.

diego.sas

Ai seria necessário analisar a necessidade de não ter um construtor vazio, visto que se mesmo você não declarar nenhum construtor na classe, o compilador te presentea com 1.

diego.sas

kkkk Boa…
Mas as IDE´s constumam apontar erros sim.
Todas as classes que utilizam o construtor default, ficará com erro.
Ae cabe ao programador ver que não tem nenhum construtor default, e adiciona-lo.

denisspitfire

certo… mas se eu nao abrir a classe que chame o motor nao vou ficar sabendo nem pela IDE que outras classes estao chamando sem parametro.
no eclipse mesmo nao faz isso, somente se voce tem a classe aberta ai sim ele avisa que a classe nao pode mais estanciar aquele objeto daquela forma

diego.sas

Então para evitar transtornos, toda vez que você alterar o construtor de uma classe, certifique-se que a mesma possui o construtor default. Assim evitará dor de cabeça.

denisspitfire

eu entendi o conceito, e que se nao tiver a classe padrao vai matar as outras etc etc…
mas pra mim nao é intuitivo o seguinte… o cara ter que sair corrigindo uma porrada de código porque ele antes disponibilizou uma solução com a classe sem parametros… mas isso tava errado e ele só percebeu anos depois e ja tinha diversas classes chamando a soluçao dele sem parametro… como ele vai corrigir sem zicar as outras partes??

eu sei que precisa criar um construtor default, e pronto…
mas isso nao tem cheiro de POG?

marciosouzajunior

denisspitfire:
certo… mas se eu nao abrir a classe que chame o motor nao vou ficar sabendo nem pela IDE que outras classes estao chamando sem parametro.
no eclipse mesmo nao faz isso, somente se voce tem a classe aberta ai sim ele avisa que a classe nao pode mais estanciar aquele objeto daquela forma

No Eclipse não tenho certeza mas no NetBeans ele verifica todas classes do projeto e avisa se tem erro em alguma.

diego.sas

denisspitfire:
eu entendi o conceito, e que se nao tiver a classe padrao vai matar as outras etc etc…
mas pra mim nao é intuitivo o seguinte… o cara ter que sair corrigindo uma porrada de código porque ele antes disponibilizou uma solução com a classe sem parametros… mas isso tava errado e ele só percebeu anos depois e ja tinha diversas classes chamando a soluçao dele sem parametro… como ele vai corrigir sem zicar as outras partes??

eu sei que precisa criar um construtor default, e pronto…
mas isso nao tem cheiro de POG?

public class Motor{

private String potencia;
private int qtdCilindros;

... getters e setters():

public Motor(){
}
public Motor(String potencia, int qtdCilindros){
this.potencia = potencia;
this.qtdCilindros = qtdCilindros;
}
}
//------------------------------------------------------------------------------------------------------
class UsaMotor{
public static void main(String args[]){
   Motor motor1 = new Motor();
   motor1.setPotencia("100C");
   motor1.setQtdCilindros(20); 

  Motor motor2 = new Motor("100C", 20); 
}
}

Me diz uma coisa qual a diferença de motor1 e motor2?

adriano_si

Denis, foi pensando exatamente nisso que foi criado o conceito de sobrecarga.

Isso não é POG, é um recurso da linguagem (embora as vezes desaconselhado).

Se você trabalha em equipes grandes e distribuídas, faz-se necessário o uso de uma IDE e sim, o Eclipse xinga até a mãe de quem fosse fazer algo parecido.

Acredite, pode parecer POG, mas não é.

Abs []

ribclauport

Bom, se você tem uma classe, e usa uma composição, deve se ater a deixar a classe com baixo acoplamento, a sua classe deve conhecer o minímo a respeito da outra
classe, isso é conseguido usando uma interface bem definida, entende-se por interface os métodos que está presentes na API.
Vamos pensar, se você altera o construtor de uma classe, e todas as classes que a usam(exemplo do motor) devem passar a construir um motor com argumentos esses
argumentos será necessários vir de algum lugar certo? Sendo assim penso que a mulher coisa no entanto é começar a discussão levando em consideração que estamos
em um fórum de java básico, e realmente, pelo menos eu, ainda não sou perito em arquitetura, design Patterns e outras nuances que envolvem os problemas estruturais de projeto, mas de qualquer forma devemos nos ater a uma coisa chamada IOC, podemos então partir do princípio que estamos falando de um problema de acoplamento certo? podemos começar pensando se a injeção de dependência ou a inversão de controle podem ou não resolver (amenizar) o nosso problema…Li um pouco de Spring, e esse framework provê formas de "injeção", sendo por setter ou por Construtor, o que acha de mudar sua classe Motor para Interface Motor?

------->IOC e Injeção de Dependência tem muitas discussões a respeito não estamos tratando do que é e como é!!!
para saber mais sobre o assunto

public interface Motor {

}

public class Carro { private String nome; private int velocidadeMaxima; private Motor motor; Carro(String nome,int velocidadeMaxima, Motor motor){ this.nome = nome; this.velocidadeMaxima = velocidadeMaxima; this.motor = motor; } }

public class MotorFerrari implements Motor {
	String tipo;

	MotorFerrari(String tipo){
		this.tipo = tipo;
	}

}

Com Spring poderiamos fazer uma injeção em Carro, desta forma de uma classe que implementa Motor, veja abaixo nos xmls que você injeta as propriedades no
construtor… pode haver erros no xml por que eu não estou testando aqui, o mais importante e a idéia…

<?xml version="1.0" encoding="ISO-8859-1"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">
<bean id="carro" class="Carro">
    <constructor-arg index="0" ref="motor"/>
</bean>
<bean id="motor" class="MotorFerrari" scope="prototype">
    <constructor-arg value="ferrari"/>
</bean>
</beans>

Ae depois seria somente carregar o xml na aplicação…

veja que agora o controle de “instanciar” um motor não é mais responsabilidade de “Carro” e sim do framework, sendo assim se você mudar o construtor, vai mudar
ali, somente no xml, e se precisar de outras implemtações vai fazer… os nomes ali talves não estejam muito bons… mas na verdade a idéia e apenas introduzir uma visão de escopo de solução…

Vejamos outra solução possível:

poderia apenas alterar a classe interna e chamar o constutor dentro de motor… e desta forma obter os valores do construtor de metodos estaticos…
desta forma suas classes não seriam os provedores dos atributos para o construtor e sim métodos utilitários, veja que a mudança é inevitável, temos
que garantir boas unidades de testes, acredito que Junit aliado a uma implementação com testes para todos os métods deixaria a mudança menos “traumática” sendo que uma vez mudando o sistema teriamos a possibilidade de rodar os testes, e encontrariamos os possíveis pontos de erro! podendo de forma mais rápida
“concertar os estragos”…bom abaixo uma possível implentação do “amenizador”

public class Motor {
	String tipo;

	Motor() {
		this(retonaTipo(), new String[] { "arg1", "arg2" });
	}

	Motor(String tipo, String... args) {
		this.tipo = tipo;
	}

	static String retonaTipo() {
		return "tipoPegoDeAlgumLugarDoMundo";
	}

}
}

Espero ter ajudadeo, e comentem o caso!

Criado 14 de março de 2012
Ultima resposta 14 de mar. de 2012
Respostas 18
Participantes 5