As classes Java a seguir pertencem ao pacote default.class A...
Gabarito comentado
Confira o gabarito comentado por um dos nossos professores
A alternativa correta é a D.
Vamos analisar detalhadamente o enunciado e as alternativas para entender por que a alternativa D é a correta.
O tema da questão envolve construtores em Java e herança. Para resolvê-la, é necessário compreender como funciona a chamada de construtores em classes derivadas (subclasses) e a relação de herança entre elas.
Quando uma classe herda de outra, o construtor da subclasse deve, explicitamente ou implicitamente, chamar um construtor da superclasse. Se não houver chamada explícita, o Java insere automaticamente uma chamada ao construtor padrão da superclasse (sem parâmetros). Se a superclasse não tiver um construtor sem parâmetros, a subclasse deve explicitamente chamar um dos construtores da superclasse, passando os parâmetros necessários.
Vamos agora justificar cada alternativa:
Alternativa D: public A2() { super(0); vb1 = va1 + va2; }
Essa alternativa é correta porque a classe A1
possui um construtor que requer um parâmetro int
. A chamada super(0)
no construtor de A2
chama adequadamente o construtor da classe A1
com um valor inteiro, evitando erros de compilação. Em seguida, a variável vb1
é inicializada corretamente.
Alternativa A: public A2() { vb1 = va1 + va2; }
Essa alternativa está incorreta porque não chama explicitamente o construtor da superclasse A1
. O compilador, então, tentaria chamar um construtor padrão (sem parâmetros) da classe A1
, que não existe, resultando em um erro de compilação.
Alternativa B: public A2(int z) { super(z); vb1 = va1 + va2; }
Embora essa alternativa não esteja errada em termos de sintaxe e lógica, o enunciado pede um construtor que não gere erro de compilação sem exigir parâmetros. Como esta alternativa exige um parâmetro int z
, ela não atende completamente o requisito da questão.
Alternativa C: public A2() { vb1 = va1 + va2; super(vb1); }
Essa alternativa está incorreta porque a chamada ao construtor da superclasse super(vb1)
deve ser a primeira instrução no construtor da subclasse. Aqui, vb1
é inicializado antes da chamada ao super
, resultando em um erro de compilação.
Alternativa E: public A2() { super(vb1); }
Essa alternativa está incorreta porque vb1
não foi inicializado antes de ser passado para o construtor da superclasse. Em Java, a variável precisa ser inicializada antes de seu uso. Portanto, o compilador geraria um erro.
Espero que a explicação tenha esclarecido suas dúvidas sobre a questão. Se precisar de mais alguma ajuda, estou à disposição!
Clique para visualizar este gabarito
Visualize o gabarito desta questão clicando no botão abaixo
Comentários
Veja os comentários dos nossos alunos
Alguns conceitos...
1) Toda classe deve possuir um construtor. Se não escrevermos, o compilador criará um construtor vazio e sem parâmetro
2) A primeira instrução dentro de um construtor deve ser um "super([...])", ou seja, uma chamada ao construtor da classe Pai. Caso a classe Pai possua um construtor sem parâmetros, então não precisamos declarar esse super, pois o compilador já faz isso pra gente. Caso não haja um construtor vazio, devemos explicitamente declarar um super na primeira linha passando os parâmetros exigidos
--------------------------------------------------------------------------
a) Não possui o super
b) Se meu A2 tiver esse construtor com parâmetro, vai dar erro lá no A3 que não tem um super que passa esse parâmetro
c) Super não está na primeira linha
d) GAB
e) Não pode usar atributo dentro do super [1]
.
[1] "An explicit constructor invocation statement in a constructor body may not refer to any instance variables or instance methods or inner classes declared in this class or any superclass, or use this or super in any expression; otherwise, a compile-time error occurs."
Fonte de [1]: https://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.8.7.1
Dá erro:
default. class A1 { protected int va1=1,va2=2;
public A1(int x) {
va1+=x; va2*=x; } }
class A2 extends A1 {
public A2() { super(0); vb1=va1+va2; }
protected int vb1=10; }
class A3 extends A2 { protected int vc1=0;
public A3(int y) {
vc1=(va1+va2)*y; } }
public class Main {
public static void main(String[] args) {
A3 o=new A3(2);
System.out.println(o.vc1); }}
O comentário do professor tá meio confuso em relação a alternativa B. Eu joguei tudo na IDE e basicamente o que passa é o seguinte: toda subclasse precisa chamar a superclasse antes de ser inicializada, se a superclasse tiver um construtor sem argumentos(), a subclasse pode implementar um construtor sem uso do "super()", porque o compilador adiciona o construtor.
Mas se o construtor da superclasse tiver algum argumento, que é o caso da A1, você precisa adicionar um construtor na subclasse com um super() e passar o argumento necessário para a inicialização da superclasse.
Logo, só sobra B, D e E. A E tenta inicializar A1 com um argumento de A1. É tipo tentar abrir um carro com a chave dentro dele próprio. Já a B e a D estão corretos.
O problema é que a questão já escreveu o método A3, que não pode ser mudado. E se você notar, o construtor de A3 não tem super(). Para fazer a alternativa B funcionar bastava escrever um "super()" em A3 e passar algum argumento. Mas como não há "super()" em A3, ele só conseguirá herdar de uma classe que possua um construtor que não necessita de argumentos, que é o caso da letra D.
B ) public A2(int z) { super(z); vb1=va1+va2; }
Tem outra coisa errada na letra B além do erro que daria com A3 por não ter um super( )
super da Alternativa B está enviando um parâmetro errado né...
Z não é um inteiro.
super(z)
Alguém concorda ?
A) nao preenche o parametro esperado pela A1(int x), pois esta inicializando o construtor da superclasse implicitamente com super(), portanto, teremos um erro de compilacao.
B) O parametro em A2(int z) nao sera preenchido quando for instanciado um objeto de A3, pois A3 esta inicializando a superclasse implicitamente com super(). Resultando assim num erro de compilacao quando um objeto de A3 for instanciado.
C) O super tem que estar na primeira linha e tambem nao tem como passar atributos da subclasse para a superclasse pelo construtor super
D) Correto, pois preenche o parametro esperado pela classe A1(int z) e nao compromete na instancia de um objeto da classe A3
E) De novo, nao tem como passar atributos da subclasse para a superclasse pelo construtor super
Clique para visualizar este comentário
Visualize os comentários desta questão clicando no botão abaixo