Duvidas com metodos de desconto

15 respostas Resolvido
java
Robson_Monteiro1

Boa noite a todos!

De já, adianto que sou iniciante. Muito iniciante :grin: .

Estou com um problema em um programa de treino que estou desenvolvendo.
Vou expor o codigo aqui e em seguida, comentar o que esta acontecendo:

================

package entities;

public class Fabrica {

private Integer camisaP = 10;
private Integer camisaM = 15;
private Integer camisaG = 20;
private double total;
private Descontos desconto;

public Integer getCamisaP() {
	return camisaP;
}

public void setCamisaP(Integer camisaP) {
	this.camisaP = camisaP;
}

public Integer getCamisaM() {
	return camisaM;
}

public void setCamisaM(Integer camisaM) {
	this.camisaM = camisaM;
}

public Integer getCamisaG() {
	return camisaG;
}

public void setCamisaG(Integer camisaG) {
	this.camisaG = camisaG;
}

public Double quantidadesCamisetas(int qtdCP, int qtdCM, int qtdCG) {
	total = (camisaP * qtdCP) + (camisaM * qtdCM) + (camisaG * qtdCG);
	return total;
}

public double getTotal() {
	return total;
}

@Override
public String toString() {
	return "Total: " + total + " R$. /nTotal com descontos: " + desconto.desconto();

================

package entities;

public class Descontos {

private double desconto10 = 0.1;
private double desconto20 = 0.2;
private double desconto30 = 0.3;
private Fabrica fabrica;
private double descontoTotal;

public double desconto() {

	double totalGeral = fabrica.getTotal();
	if (totalGeral <= 100.0) {
		descontoTotal = totalGeral / desconto10;
	} else if (totalGeral <= 150.00) {
		descontoTotal = totalGeral / desconto20;
	} else {
		descontoTotal = totalGeral / desconto30;
	}
	return descontoTotal;
}

public String toString() {
	return "." + descontoTotal;
}

}

================

package entities;

import java.util.Locale;
import java.util.Scanner;

public class Program {
public static void main(String[] args) {

Locale.setDefault(Locale.US);
	Scanner sc = new Scanner(System.in);
	
	Fabrica fabrica = new Fabrica();
	
	System.out.println("Bem vindo a loja de camisetas!");
	System.out.println("Digite o total de camisas por tamanho desejadas:");
	System.out.print("Camisa P: ");
	int p = sc.nextInt();
	System.out.print("Camisa M: ");
	int m = sc.nextInt();
	System.out.print("Camisa G: ");
	int g = sc.nextInt();
	
	fabrica.quantidadesCamisetas(p, m, g);
	
	System.out.println(fabrica);
	
	sc.close();
}

}

=============ERRO=========

Exception in thread main java.lang.NullPointerException: Cannot invoke entities.Descontos.desconto() because this.desconto is null

at entities.Fabrica.toString(Fabrica.java:46)

at java.base/java.lang.String.valueOf(String.java:3365)

at java.base/java.io.PrintStream.println(PrintStream.java:1047)

at entities.Program.main(Program.java:25)

==========

Este erro acontece quando eu tento usar o metodo de desconto. Más não consegui intender exatamente o que pode estar errado. (muito leigo por sinal);

Alguem poderia me ajudar? Desculpem o incômodo. :pensive:

15 Respostas

RoinujNosde

Na sua classe Fabrica, vc declarou o campo desconto, mas não o inicializou.
Tente assim:
private Descontos desconto = new Descontos();

Robson_Monteiro1

Fiz isso.
Agora dá outro erro informando que o fabrica.getTotal(); é nulo.

==========

Cannot invoke “entities.Fabrica.getTotal()” because “this.fabrica” is null

RoinujNosde

É a mesma coisa.
Na classe Descontos tem um campo fabrica que não foi inicializado.

staroski

Sua classe Fabrica possui um atributo do tipo Descontos.
Sua classe Descontos possui um atributo do tipo Fabrica.
Essa modelagem está estranha, porque ambas dependem entre si?

Robson_Monteiro1

da um erro pior ainda se eu instanciar

Robson_Monteiro1

Na fabrica, coloquei para usar no toString();.

=========

<a class="mention" href="/u/override">@Override</a>

public String toString() {

return "Total: " + getTotal() + " R$. /nTotal com descontos: " + desconto.desconto();

}
RoinujNosde

Um stackoverflow?

Fabrica depende de Descontos e Descontos depende de Fabrica.
Ao instanciar Fabrica, instancia Descontos, que instancia Fabrica, etc, etc loop infinito.

Melhor repensar o modelo como o @staroski comentou.

Robson_Monteiro1

estou reescrevendo. Vamos ver no que dá

A

Uma sugestão é você tentar entender porque você precisa do objeto Fabrica em Descontos e porque você precisa do objeto Descontos em Fabrica.

No primeiro caso: por que existe um objeto Fabrica em Descontos?
Lendo seu código, o método desconto usa fabrica para pegar o total:

double totalGeral = fabrica.getTotal();

Uma maneira simples de simplificar isso é ao invés de ter um atributo Fabrica no objeto Desconto, você pode passar fabrica como parâmetro:

public double desconto(Fabrica fabrica) {

	double totalGeral = fabrica.getTotal();
	if (totalGeral <= 100.0) {
		descontoTotal = totalGeral / desconto10;
	} else if (totalGeral <= 150.00) {
		descontoTotal = totalGeral / desconto20;
	} else {
		descontoTotal = totalGeral / desconto30;
	}
	return descontoTotal;
}

A lógica fica igual, e na hora que você for chamar o método (de dentro da fábrica) é só fazer:

return "Total: " + total + " R$. /nTotal com descontos: " + desconto.desconto(this);
```
Robson_Monteiro1

fiz isso.

agora da este erro:

==================

Exception in thread main java.lang.NullPointerException: Cannot invoke entities.Descontos.desconto(entities.Fabrica) because this.desconto is null

at entities.Fabrica.toString(Fabrica.java:51)

at java.base/java.lang.String.valueOf(String.java:3365)

at java.base/java.io.PrintStream.println(PrintStream.java:1047)

at Program.main(Program.java:27)
Robson_Monteiro1

Tive uma ideia, mas não funcionou.

Coloquei que a classe Descontos extendia Fabrica, tirei Fabrica de parametro do metodo e puxei o .getTotal direto.

Da o mesmo erro…

Robson_Monteiro1

Sei que poderia fazer isso direto na propria classe, mas a possibilidade de fazer de outra classe me deixou curioso. E resolver este problema pode me ser util no futuro…

forma de fazer na mesma classe fabrica:

===============

Double desconto;

Public void setDesconto(Double desconto){this.desconto=desconto};

Public Double getDesconto(){return desconto};

//    para descontos em casas decimais, sendo 10% = 0,1

Public Double valorFinal(){

return (valordoProduto*desconto);

};
E
Solucao aceita

Segue seu codigo, fiz apenas as modificações para que funcione sem validar nada de calculos ou regras. Compare com o seu original e entenda as diferenças. ( leve em consideração que existem inumeras maneiras de fazer.)

//Classe descontos

public class Descontos {

private static double	desconto10	= 0.1;
private static double	desconto20	= 0.2;
private static double	desconto30	= 0.3;
private static double	descontoTotal;

public static double desconto(double totalGeral) {

	if (totalGeral <= 100.0) {
		descontoTotal = totalGeral / desconto10;
	} else if (totalGeral <= 150.00) {
		descontoTotal = totalGeral / desconto20;
	} else {
		descontoTotal = totalGeral / desconto30;
	}
	return descontoTotal;
}

public String toString() {
	return "." + descontoTotal;
}
}

//Classe Fabrica

public class Fabrica {

private Integer	camisaP	= 10;
private Integer	camisaM	= 15;
private Integer	camisaG	= 20;
private double	total;

public int getCamisaP() {
	return camisaP;
}

public void setCamisaP(int camisaP) {
	this.camisaP = camisaP;
}

public Integer getCamisaM() {
	return camisaM;
}

public void setCamisaM(int camisaM) {
	this.camisaM = camisaM;
}

public Integer getCamisaG() {
	return camisaG;
}

public void setCamisaG(int camisaG) {
	this.camisaG = camisaG;
}

public void quantidadesCamisetas(int qtdCP, int qtdCM, int qtdCG) {
	total = (camisaP * qtdCP) + (camisaM * qtdCM) + (camisaG * qtdCG);
	setTotal(total);
}

public double getTotal() {
	return total;
}

@Override
public String toString() {
	return "Total: " + total + " R$. /nTotal com descontos: " + Descontos.desconto(getTotal());
}

public void setTotal(double total) {
	this.total = total;
}
}

//Classe Program

import java.util.Locale;
import java.util.Scanner;

 public class Program {
public static void main(String[] args) {

	Locale.setDefault(Locale.US);
	Scanner sc = new Scanner(System.in);

	Fabrica fabrica = new Fabrica();

	System.out.println("Bem vindo a loja de camisetas!");
	System.out.println("Digite o total de camisas por tamanho desejadas:");
	System.out.print("Camisa P: ");
	int p = sc.nextInt();
	System.out.print("Camisa M: ");
	int m = sc.nextInt();
	System.out.print("Camisa G: ");
	int g = sc.nextInt();

	fabrica.quantidadesCamisetas(p, m, g);

	System.out.println(fabrica);

	sc.close();
}
}

Espero qeu ajude a entender.

staroski

No mundo real faz sentido você dizer que um desconto é uma fábrica?
Se não fizer, então não faz sentido a classe Descontos estender a classe Fabrica.

Robson_Monteiro1

Caramba… quanto erro tinha nesse meu codigo…

fiz dessa forma ai e funcionou. mudou bastante coisa!

aos poucos vou me habituando :grin:

Muito obrigado!

Criado 23 de março de 2021
Ultima resposta 25 de mar. de 2021
Respostas 15
Participantes 5