Problema "simples" com herança

Porque a chamada do método q.getAreaQuadrado(); não está retornando a àrea do quadrado ?

É uma hierarquia de quatro níveis, aqui só vou mostrar as classes necessárias.

A saida do programa é:
[color=green]no método Quadrado.getAreaQuadrado
no método LadosIguais.getArea
Depois de chamar Quadrado.getAreaQuadrado[/color]

public class Teste {
	public static void main(String[] args) {
		Quadrado q = new Quadrado (2,2,2,2);
		
		q.getAreaQuadrado();
		System.out.println("Depois de chamar Quadrado.getAreaQuadrado");
	}
	
}

[code]public class Quadrado extends LadosIguais {

public Quadrado (float l1, float l2, float l3, float l4){
	super(l1, l2, l3, l4);
	super.setArea();
}

public String getAreaQuadrado(){
	System.out.println("no método Quadrado.getAreaQuadrado");
	return String.format("\nA area do quadrado é: %.2f", super.getArea());
}

}
[/code]

[code]
public class LadosIguais extends Quadrilatero{
private float area;

public LadosIguais (float l1, float l2, float l3, float l4){
	super(l1, l2, l3, l4);
}

public void setArea(){

//cacula no caso de ser um retangulo
if (super.getLados2(0) == super.getLados2(1))
;
else
area = super.getLados2(0) * super.getLados2(1);

//calcula no caso de ser um quadrado
if (super.getLados2(0)==super.getLados2(1) && super.getLados2(1) == super.getLados2(2))
area = super.getLados2(0)*2;
}

public float getArea(){
	System.out.println("no método LadosIguais.getArea");
	return area;
}

}[/code]

[code]public class Quadrilatero {
private float lado1, lado2, lado3, lado4;
private float lados[] = new float[4];

public Quadrilatero (float l1, float l2, float l3, float l4){
	lado1 = l1;
	lado2 = l2;
	lado3 = l3;
	lado4 = l4;
	
	lados[0] = lado1;
	lados[1] = lado2;
	lados[2] = lado3;
	lados[3] = lado4;
}

public float getLados2(int a){
	return lados [a];		
}

}[/code]

Nossa cara… que hierarquia complicada!

E que negócio é esse aqui?

if (super.getLados2(0) == super.getLados2(1)) ; else area = super.getLados2(0) * super.getLados2(1);

Não seria mais lógico fazer isso aqui?

if (super.getLados2(0) != super.getLados2(1)) area = super.getLados2(0) * super.getLados2(1);

Você só não está imprimindo a área do quadrado que você retorna!

Sua classe Teste deveria ser:

[code]public class Teste {
public static void main(String[] args) {
Quadrado q = new Quadrado (2,2,2,2);

    System.out.println(q.getAreaQuadrado()); //O erro estava nessa linha
    System.out.println("Depois de chamar Quadrado.getAreaQuadrado");
}

}[/code]

Agora, algumas dicas para seu programa:

  1. Elimine as variáveis lado1, lado2, lado3 e lado4 da classe quadrilátero. Elas não servem para nada e você sempre poderá usar a matriz;

  2. LadosIguais me parece ser mais uma propriedade do que uma classe. Ainda sim, se for uma classe, faça com que o construtor aceite apenas dois lados. Assim você garante que o usuário não passará dados inválidos. Ele ficaria assim:

public LadosIguais (float l1, float l2){ super(l1, l1, l2, l2); }

Outra coisa que essa abordagem facilita é que o calculo de um quadrado fica rigosamente igual. O método setArea poderia ser:
public void setArea(){
return getLado(0) * getLado(2);
}

  1. Faça o mesmo para a classe quadrado. Como todos os lados são iguais, o construtor poderia ser:

public Quadrado(float lado) { super(lado, lado); }

  1. Não há necessidade do método getAreaQuadrado(), já que a classe pai já define getArea.

  2. Melhore o nome da classe LadosIguais. Ela tem quantos lados iguais? Se forem 2 pares, chame-a de Retangulo. Se forem os 4, não seria a própria classe quadrado? Se você quer apenas 2 lados, chame-a de DoisLadosIguais, mas estará faltando o método para calcular a área de um trapézio.

O código com as dicas aplicadas está em anexo.

Valeu, estava faltando mesmo imprimir o método na classe Quadrado. Eu achei que String.format() funcionasse igual o Printf().

Quanto as dicas, a nº 1 já segui.
as nº 2 e nº 3 segui mas adaptei, pois esta classe LadosIguais vai ser herdada não só pela Quadrado, mas também pela Retangulo, veja:

Com apenas o lado superior e direito é possivel dizer se ele é um retangulo ou um quadrado, e com apenas um lado calculamos um quadrado. Por isso modifiquei a classe LadosIguais, que agora tem dois construtores sobrecarregados:

[code]

public class LadosIguais extends Quadrilatero{
private float area;

//construtor chamado na classe Quadrado
public LadosIguais (float lSuperior){
super(lSuperior,lSuperior,lSuperior,lSuperior);
}

//construtor chamado na classe Retangulo
public LadosIguais (float lSuperior, float lDireito){
super(lSuperior, lDireito, lSuperior, lDireito);
}

public void setArea(){

//cacula no caso de ser um retangulo
if (super.getLados2(0) != super.getLados2(1))
area = super.getLados2(0) * super.getLados2(1);
//calcula no caso de ser um quadrado
else
area = super.getLados2(0)*2;
}

public float getArea(){
	return area;
}

}[/code]
A classe Quadrado:

[code]public class Quadrado extends LadosIguais {

public Quadrado (float lados){
	super(lados);
	super.setArea();
}

public String getAreaQuadrado(){
	return String.format("\nA area do quadrado é: %.2f", super.getArea());
}

}[/code]
A classe Quadrilatero:

[code]public class Quadrilatero {
private float lados[] = new float[4];

public Quadrilatero (float lSuperior, float lDireito, float lInferior, float lEsquerdo){
	lados[0] = lSuperior;
	lados[1] = lDireito;
	lados[2] = lInferior;
	lados[3] = lEsquerdo;
}

public float getLados2(int a){
	return lados [a];		
}

}[/code]

Aham - * 2 multiplica por 2, não eleva ao quadrado como você está pensando. (Em Fortran “** 2” eleva ao quadrado, mas você não está programando em Fortran).

[quote=Edson Watanabe][quote]
area = super.getLados2(0)*2;
[/quote]

Aham - * 2 multiplica por 2, não eleva ao quadrado como você está pensando. (Em Fortran “** 2” eleva ao quadrado, mas você não está programando em Fortran).[/quote]

Ok voce está certo. Então em Java tenho duas alternativas, ou simplesmente multiplico getLados2(0) * getLados2(0) ou uso o método Math.pow da classe java.lang.Math que é implicitamente importada.
Então ficou assim:

area = (float)Math.pow((double)super.getLados2(0),2);

Um trapézio pode ter 2 lados iguais e dois diferentes. Basta que os dois lados formem o mesmo ângulo com a base (embora para lados opostos). Por exemplo, 30º e 120º em sentido horário. Isso não tornaria ele apto a ser filho de LadosIguais? Se não tornaria, então lados iguais refere-se a quadriláteros. Melhor chamar a classe de Quadrilatero ou Retangulo (e eliminar a classe retângulo, já que todo quadrilátero formado por ângulos internos retos é um retângulo, e isso inclui o quadrado.

Engraçado como um problema aparentemente simples pode ser tão complexo …

Um quadrilátero tem obviamente 4 lados e é isso a unica coisa que o faz especial. Um losango e um quadrado são quadrilateros com iguais comprimentos dos lados, todos iguais, e mesmo assim a áre não é calculada da mesma forma.

Parece-me que o problema está em tentar criar uma formula generica para o calculo da area quando na verdade essa é a tarefa que deve ser delegada a quem a sabe fazer : a própria classe.

Eis uma estrutura


abstract Quadrilatero {

  int[] lados;

 public (int ... tamanhoDosLados){
          if (tamanhoDosLados.length != 4){
              throw new IllegalArgumentException("Um quadrilatero tem que ter 4 lados. Apenas " + tamanhoDosLados.length + " foram fornecidos");
          }
 this.lados = tamanhoDosLados;

 }
  public int tamanhoDoLado (int ladoIndex){
          return lado[ladoIndex]
  }

  public int perimetro(){
 // o algoritmo do perimetro é generico.
           return lado[0] + lado[1] + lado[2] + lado[3];
  }

  abstract int area(); // o da area não

}



public Retangulo extends Quadrilatero implements Paralelogramo{

     public Retangulo (int ... lados){
           super(lados)
     }
     
      public int area (){
           // encontra os lados diferentes e multiplica 
          int[] nlados = Arrays,copyOf(lados, 4);
          Arrays.sort(nlados);
          return nlados[0]*nlados[3];
// poderia ser outro codigo. tou com preguiça de fazer um for
      }

}


public Quadrado extends Retangulo {

     public Quadrado (int lado){ // um so argumento
           super(lado,lado,lado,lado);
     }
     
      public int area (){
           return nlados[0] * nlados[0];
      }

}

public Losango extends Quadrilatero implements Paralelogramo{

    double anguloAgudo;
 // angulo em radianos
     public Losango (int lado, double anguloAgudo){
           super(lado,lado,lado,lado);
this.anguloAgudo = anguloAgudo; 
     }
     
      public int area (){
           return nlados[0] * Math.sin(anguloAgudo);
      }

}


 }

Lados todos têm, mas nem sempre a Área depende só dos lados (losango)… por isso area tem que ser abstrat e implementada por cada classe em separado

Quadrado é um caso particular de retangulo e retangulo é um caso de Quadrilatero. Portanto não tem como subtituir Quadrilatero por retangulo. Um losango é um Quadrilatero e não é um retangulo.

Claro, vc incluiu essas dos angulos internos para excluir coisas como o losango… :wink: mas isso é violar a herança de Quadrilatero

Exatamente, foi o que falei. Se ele não considera o losango e só figuras de angulos internos iguais, poderia substituir por retangulo sem problemas. Caso contrário, já não poderia chamar a classe de retângulo, como vc falou. Tudo vai depender do escopo da aplicação dele.

  1. Implemente uma hierarquia de classes que represente figuras geométricas com quatro ângulos, onde temos como classes filhas retângulos e losangos. Neste caso, utilizando o conceito de polimorfismo, implemente um método tipo_figura, onde este método receba parâmetros para calcular o tipo de figura (se os ângulos internos forem igual a 90 graus a figura é um retângulo, se os ângulos internos forem diferente de 90 graus, mas iguais dois a dois, a figura é um losango). Lembre-se: deve-se utilizar obrigatoriamente o método super nos construtores das classes filhas

[quote=Toni_Fatec]Porque a chamada do método q.getAreaQuadrado(); não está retornando a àrea do quadrado ?

É uma hierarquia de quatro níveis, aqui só vou mostrar as classes necessárias.

A saida do programa é:
[color=green]no método Quadrado.getAreaQuadrado
no método LadosIguais.getArea
Depois de chamar Quadrado.getAreaQuadrado[/color]

public class Teste {
	public static void main(String[] args) {
		Quadrado q = new Quadrado (2,2,2,2);
		
		q.getAreaQuadrado();
		System.out.println("Depois de chamar Quadrado.getAreaQuadrado");
	}
	
}

[code]public class Quadrado extends LadosIguais {

public Quadrado (float l1, float l2, float l3, float l4){
	super(l1, l2, l3, l4);
	super.setArea();
}

public String getAreaQuadrado(){
	System.out.println("no método Quadrado.getAreaQuadrado");
	return String.format("\nA area do quadrado é: %.2f", super.getArea());
}

}
[/code]

[code]
public class LadosIguais extends Quadrilatero{
private float area;

public LadosIguais (float l1, float l2, float l3, float l4){
	super(l1, l2, l3, l4);
}

public void setArea(){

//cacula no caso de ser um retangulo
if (super.getLados2(0) == super.getLados2(1))
;
else
area = super.getLados2(0) * super.getLados2(1);

//calcula no caso de ser um quadrado
if (super.getLados2(0)==super.getLados2(1) && super.getLados2(1) == super.getLados2(2))
area = super.getLados2(0)*2;
}

public float getArea(){
	System.out.println("no método LadosIguais.getArea");
	return area;
}

}[/code]

[code]public class Quadrilatero {
private float lado1, lado2, lado3, lado4;
private float lados[] = new float[4];

public Quadrilatero (float l1, float l2, float l3, float l4){
	lado1 = l1;
	lado2 = l2;
	lado3 = l3;
	lado4 = l4;
	
	lados[0] = lado1;
	lados[1] = lado2;
	lados[2] = lado3;
	lados[3] = lado4;
}

public float getLados2(int a){
	return lados [a];		
}

}[/code][/quote]

  1. como resolver essa qustão: Sabe-se que os valores de glicose no sangue de uma pessoa em jejum pode indicar se esta pessoa possui ou não um quadro de diabetes. Crie um método utilizando a estrutura de controle SWITCH-CASE, para calcular se uma pessoa esta com suspeita ou não de diabetes, utilizando as informações abaixo:

CONDIÇÃO VALORES (mg/dL)
NORMAL < 80
LIMIAR 80-120
SUSPEITA DE DIABETES >120

[quote=Toni_Fatec]Porque a chamada do método q.getAreaQuadrado(); não está retornando a àrea do quadrado ?

É uma hierarquia de quatro níveis, aqui só vou mostrar as classes necessárias.

A saida do programa é:
[color=green]no método Quadrado.getAreaQuadrado
no método LadosIguais.getArea
Depois de chamar Quadrado.getAreaQuadrado[/color]

public class Teste {
	public static void main(String[] args) {
		Quadrado q = new Quadrado (2,2,2,2);
		
		q.getAreaQuadrado();
		System.out.println("Depois de chamar Quadrado.getAreaQuadrado");
	}
	
}

[code]public class Quadrado extends LadosIguais {

public Quadrado (float l1, float l2, float l3, float l4){
	super(l1, l2, l3, l4);
	super.setArea();
}

public String getAreaQuadrado(){
	System.out.println("no método Quadrado.getAreaQuadrado");
	return String.format("\nA area do quadrado é: %.2f", super.getArea());
}

}
[/code]

[code]
public class LadosIguais extends Quadrilatero{
private float area;

public LadosIguais (float l1, float l2, float l3, float l4){
	super(l1, l2, l3, l4);
}

public void setArea(){

//cacula no caso de ser um retangulo
if (super.getLados2(0) == super.getLados2(1))
;
else
area = super.getLados2(0) * super.getLados2(1);

//calcula no caso de ser um quadrado
if (super.getLados2(0)==super.getLados2(1) && super.getLados2(1) == super.getLados2(2))
area = super.getLados2(0)*2;
}

public float getArea(){
	System.out.println("no método LadosIguais.getArea");
	return area;
}

}[/code]

[code]public class Quadrilatero {
private float lado1, lado2, lado3, lado4;
private float lados[] = new float[4];

public Quadrilatero (float l1, float l2, float l3, float l4){
	lado1 = l1;
	lado2 = l2;
	lado3 = l3;
	lado4 = l4;
	
	lados[0] = lado1;
	lados[1] = lado2;
	lados[2] = lado3;
	lados[3] = lado4;
}

public float getLados2(int a){
	return lados [a];		
}

}[/code][/quote]

[quote=sergiotaborda]Engraçado como um problema aparentemente simples pode ser tão complexo …

Um quadrilátero tem obviamente 4 lados e é isso a unica coisa que o faz especial. Um losango e um quadrado são quadrilateros com iguais comprimentos dos lados, todos iguais, e mesmo assim a áre não é calculada da mesma forma.

Parece-me que o problema está em tentar criar uma formula generica para o calculo da area quando na verdade essa é a tarefa que deve ser delegada a quem a sabe fazer : a própria classe.

Eis uma estrutura


abstract Quadrilatero {

  int[] lados;

 public (int ... tamanhoDosLados){
          if (tamanhoDosLados.length != 4){
              throw new IllegalArgumentException("Um quadrilatero tem que ter 4 lados. Apenas " + tamanhoDosLados.length + " foram fornecidos");
          }
 this.lados = tamanhoDosLados;

 }
  public int tamanhoDoLado (int ladoIndex){
          return lado[ladoIndex]
  }

  public int perimetro(){
 // o algoritmo do perimetro é generico.
           return lado[0] + lado[1] + lado[2] + lado[3];
  }

  abstract int area(); // o da area não

}



public Retangulo extends Quadrilatero implements Paralelogramo{

     public Retangulo (int ... lados){
           super(lados)
     }
     
      public int area (){
           // encontra os lados diferentes e multiplica 
          int[] nlados = Arrays,copyOf(lados, 4);
          Arrays.sort(nlados);
          return nlados[0]*nlados[3];
// poderia ser outro codigo. tou com preguiça de fazer um for
      }

}


public Quadrado extends Retangulo {

     public Quadrado (int lado){ // um so argumento
           super(lado,lado,lado,lado);
     }
     
      public int area (){
           return nlados[0] * nlados[0];
      }

}

public Losango extends Quadrilatero implements Paralelogramo{

    double anguloAgudo;
 // angulo em radianos
     public Losango (int lado, double anguloAgudo){
           super(lado,lado,lado,lado);
this.anguloAgudo = anguloAgudo; 
     }
     
      public int area (){
           return nlados[0] * Math.sin(anguloAgudo);
      }

}


 }

Lados todos têm, mas nem sempre a Área depende só dos lados (losango)… por isso area tem que ser abstrat e implementada por cada classe em separado[/quote]