Oi pessoas.
Queria saber como impedir uma classe de ser instanciada.
Conheço 2 maneiras: fazer a classe como abtrata e definir como o construtor como private.
Existe mais alguma maneira?
Como impedir uma classe de ser instanciada?
16 Respostas
Você poderia lançar uma exceção nos construtores públicos.
Oi pessoas.
Queria saber como impedir uma classe de ser instanciada.
Conheço 2 maneiras: fazer a classe como abtrata e definir como o construtor como private.
Existe mais alguma maneira?
mas com construtor private eu instancio dentro da mesma classe…
Singleton.
Se vc criar uma classe onde tudo é static, instanciar não faria diferença.
um dúvida: pq não pode ser instanciada :?: qual tua regra :?: vai contra princípios da OO…
se não puder ser extends… etc… tudo bem…mas instanciada…
Singleton.
http://pt.wikipedia.org/wiki/SingletonSingleton permite UMA instância, não?
[]'s
Sim… singleton, normalmente, pede um construtor privado… o que não tem nada ligado com o tópico…
Entendi mal. Falou ele explicar pra que exatamente não quer que a classe seja instanciada…
peczenyj,
Humm... Minha classe está assim:/**
* Classe que contem os precos de mercado de cada produto, os custos de cada produto por litro e o tempo de producao dos produtos
*/
public class Valores
{
// Campos dos precos
private static final double PREC0_LEITE = 0.42;
private static final double PRECO_PASTEURIZADO = 1.40;
private static final double PRECO_IOGURTE = 1.22;
private static final double PRECO_QUEIJO = 3.67; // O valor vem do calculo 0.022 * 166.67
// Campos do custo de cada producao
private static final double CUSTO_LEITE = 1;
private static final double CUSTO_PASTEURIZADO = 2;
private static final double CUSTO_IOGURTE = 3;
private static final double CUSTO_QUEIJO = 4;
}
Sem métodos, sem construtor, só as variáveis. Eu quero acessar da mesma maneira que o acesso ao valor PI da classe Math acontece.
Por exemplo:
Valores.CUSTO_LEITE;
Mas se alguém por ventura tentar instanciar a classe, ela vai ser instanciada e não vai ter nada pra fazer, além de ter uma referência para um objeto na heap.
Existe alguma maneira de impedir que qualquer outra classe instancie ela?
ps.: A da exception me pareceu uma boa.
Ainda, outra dúvida, teria como usar um Enum?
@javabuntu,
Acho que não vai contra os princípios da Orientação a Objetos não cara...
Abraço.
Existem, no Java, apenas duas formas de impedir uma classe ser instânciada (e AMBOS devem ocorrer):
1- Não dar “new”.
2- Não herdar essa classe.
Definir uma classe abstrata diz apenas que somente seus filhos podem instanciá-lo via “super”.
Definir um construtor privado diz apenas que a própria classe pode instanciá-lo.
peczenyj, Humm... Minha classe está assim:/** * Classe que contem os precos de mercado de cada produto, os custos de cada produto por litro e o tempo de producao dos produtos */ public class Valores { // Campos dos precos private static final double PREC0_LEITE = 0.42; private static final double PRECO_PASTEURIZADO = 1.40; private static final double PRECO_IOGURTE = 1.22; private static final double PRECO_QUEIJO = 3.67; // O valor vem do calculo 0.022 * 166.67 // Campos do custo de cada producao private static final double CUSTO_LEITE = 1; private static final double CUSTO_PASTEURIZADO = 2; private static final double CUSTO_IOGURTE = 3; private static final double CUSTO_QUEIJO = 4; }Sem métodos, sem construtor, só as variáveis. Eu quero acessar da mesma maneira que o acesso ao valor PI da classe Math acontece.
Por exemplo:Valores.CUSTO_LEITE;Mas se alguém por ventura tentar instanciar a classe, ela vai ser instanciada e não vai ter nada pra fazer, além de ter uma referência para um objeto na heap.
Existe alguma maneira de impedir que qualquer outra classe instancie ela?ps.: A da exception me pareceu uma boa.
Ainda, outra dúvida, teria como usar um Enum?
@javabuntu,
Acho que não vai contra os princípios da Orientação a Objetos não cara...
Abraço.
Dede,
você já ouviu falar de enum? Acho que é a melhor alternativa.
Leonardo,
Aham, é o que eu falei no tópico que você ‘quotou’. 
Abraço.
Eu olhei de novo seu comentário e não vi o enum, que pra mim seria assim:
public enum Produto {
LEITE (new BigDecimal("0.42"), new BigDecimal("1.00")),
PASTEURIZADO (new BigDecimal("1.40"), new BigDecimal("2.00")),
IOGURTE (new BigDecimal("1.22"), new BigDecimal("3.00")),
QUEIJO (new BigDecimal("3.67"), new BigDecimal("4.00"));
private BigDecimal custo;
private BigDecimal precoVenda;
private Produto(BigDecimal custo, BigDecimal precoVenda) {
this.custo = custo;
this.precoVenda = precoVenda;
}
public BigDecimal getCusto() {
return custo;
}
public BigDecimal getPrecoVenda() {
return precoVenda;
}
}
Eu sei que não deveria te ajudar a esse ponto, mas não dá pra explicar sem mostrar código.
Oi pessoas.
Queria saber como impedir uma classe de ser instanciada.
Conheço 2 maneiras: fazer a classe como abtrata e definir como o construtor como private.
Existe mais alguma maneira?
Impedir a classe de ser instanciada (caso geral): impossivel. A classe sempre se pode instanciar a si mesma.
Impedir a classe de ser instancida por outros objetos de classes diferentes : coloque o construtor private.
Herança não tem a haver com instanciação. Se vc cria uma nova classe é essa classe e nunca a mae que é instanciada. Contudo, mesmo que a classe herde da outra, se o construtor é private ela não consegue ser herdada. (o compilador não aceita)
Se o construtor é private , implica que a classe não pode ser herdada , logo , a classe deve ser final.
Portanto, coloque a classe final e private para impedir que ela seja instanciada por outras classes.
Abstract + private não tem sentido. Abstract quer dizer que ela tem que ser herdada para funcionar, mas private impede isso ( o construtor não é visivel à classe filha). Funciona, mas é errado.
Se vc está tentando criar uma classe utilitária ( daqules que só têm métodos estáticos) é correto esconder o construtor e colocar final. em especial se vc está tentando usar algum padrão como singleton ou registry.
Lançar exception em construtores é muito,muito , muito mau. Vc vai para o inferno se fizer isso. :twisted:
NUNCA faça isso. ( a unica exceção a esta regra é IllegalArgumentException)
não so tem como deve. Deveria usar Enum. Mas no seu caso, não sei se ajuda.
A ideia de Math.PI é a de uma Constante. Contante é um static final e Não tem nada a ver com instanciação.
Contudo, Math não é instanciável, exactamente porque não tem estado ( não tem attributos não-constantes)
E é isso que vc quer.
Não só não vai contra os principios, como é de principio fazer isso. Se a classe não deve ser instanciada, então ela não deve ser mesmo. Nada de POG de achar que só porque a classe só tem métodos estaticos não ha problema em deixar que seja criada. Na prática não ha problema, além de consumir memória. Mas por outro lado
significa que o programador é ruim.
Pois é. Não sabia dessa com exception em construtores.
Usei Enum mesmo.
/**
* Enum que armazena as variaveis constantes do preco de venda, do custo e do tempo
*/
public enum Valores
{
// Objetos
LEITE_PURO(0.42, 0.30, 2), LEITE_PASTEURIZADO(1.43, 0.20, 4), LEITE_FERMENTADO(11.20, 0.6, 4), IOGURTE(3, 0.5, 8), QUEIJO(3.22, 1.8, 10);
private final double venda;
private final double custo;
private final int tempo;
/**
* Construtor
* @param novoPrecoVenda, novoPrecoCusto, novoTempoLitro
*/
Valores(double novoPrecoVenda, double novoPrecoCusto, int novoTempoLitro)
{
this.venda = novoPrecoVenda;
this.custo = novoPrecoCusto;
this.tempo = novoTempoLitro;
}
/**
* Metodo acessador do preco de venda
* @return venda
*/
public double getVenda()
{
return venda;
}
/**
* Metodo acessador do custo por litro
* @return custo
*/
public double getCusto()
{
return custo;
}
/**
* Metodo acessador do tempo necessario para produzir 1 litro
* @return tempo
*/
public int getTempo()
{
return tempo;
}
}
E acesso os valores da seguinte maneira:
lucroTotal = lucroTotal + (((double)q * valores[contador].getVenda()) - ((double)q * valores[contador].getCusto()));
auxiliar = (double)q * valores[contador].getTempo();
É certo fazer dessa maneira?
Abraço.
editado
Li agora seu post Leonardo. Ficou um pouco diferente, mas acredito que no fim das contas o resultado seja o mesmo.