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?
Você poderia lançar uma exceção nos construtores públicos.
[quote=dedejava]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?[/quote]
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…
[quote=Schuenemann]Singleton.
http://pt.wikipedia.org/wiki/Singleton[/quote]
Singleton permite UMA instância, não?
[]'s
[quote=crpablo][quote=Schuenemann]Singleton.
http://pt.wikipedia.org/wiki/Singleton[/quote]
Singleton permite UMA instância, não?
[]'s[/quote]
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:
[code]/**
- 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;
}
[/code]
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?
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.
[quote=dedejava]peczenyj,
Humm… Minha classe está assim:
[code]/**
- 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;
}
[/code]
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?
Acho que não vai contra os princípios da Orientação a Objetos não cara…
Abraço.
[/quote]
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.
[quote=dedejava]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?[/quote]
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.