Como impedir uma classe de ser instanciada?

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.

1 curtida

[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?

@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.

[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?

@javabuntu,

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’. :slight_smile:

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.