Olá, estou estudando Herança e me veio essa dúvida:
Quando eu crio uma classe abstrata ela não pode ser instãnciada, correto.
Mas mesmo assim eu consigo criar objetos dessa classe e até executar métodos, do que adianta então ela não poder ser instãnciada já que estou usando um construtor default (vazio) não vai mudar nada, correto? :?:
Quando você define uma classe abstrata:
a) Ela não pode ser instanciada, e ponto.
b) Você não consegue criar objetos dessa classe abstrata. Você só consegue criar (instanciar) objetos de classes concretas (por exemplo, que estendem classes abstratas).
Você pode definir uma variável cujo tipo é essa classe abstrata.
Cuidado que variáveis não são objetos e sim referências para objetos.
É como se fosse um cartãozinho com um endereço de uma casa - o cartão não tem uma casa e sim apenas uma referência.
Essa é a confusão mais grave que 50% dos programadores Java fazem - e depois de 10 anos de Java tem muita gente que ainda faz essa confusão.
c) Você pode executar métodos definidos na classe abstrata ou na classe concreta que estende essa classe abstrata, através da variável que você usou para referenciar o objeto.
d) O construtor default de uma classe abstrata serve apenas para poder ser chamado (indiretamente) pelo construtor default da classe concreta que estende essa classe abstrata, isso no caso em que a classe abstrata também tem apenas o construtor default.
Como você deve saber, java.lang.Number é uma classe abstrata, e java.lang.Integer é uma classe concreta que estende essa classe abstrata.
Você pode referenciar um objeto da classe java.lang.Integer (uma classe concreta) de três maneiras (veja que não preciso fazer cast nenhum) :
Object obj = new Integer(111);
Number num = new Integer(222);
Integer intg = new Integer (333);
Nos três casos, as variáveis acima referenciam objetos da classe concreta Integer, mas são variáveis de tipos diferentes.
No caso de obj, você pode chamar os métodos toString(), hashcode() e equals().
No caso de num, além dos métodos de Object listados acima, você pode chamar os métodos intValue(), doubleValue() etc. (veja o javadoc da classe Number)
No caso de intg, não há métodos novos definidos (na verdade, há uma pancada de métodos estáticos que são exclusivos de java.lang.Integer, mas eles não vêm ao caso nessa explicação).
Portanto, o uso de variáveis com tipos diferentes não altera o tipo do objeto referenciado. Só os métodos que podem ser chamados é que variam - você pode chamar menos ou mais métodos dependendo do tipo da variável.
Ola CamilaPires sei que faz um tempo que este post foi criado, mais respondendo sua pergunta o construtor de uma classe abstract faz diferença sim.
Quando é realizado uma instância de um objeto se a classe Concreta implementa uma classe abstract,
o construtor da classe abstract é chamado primeiro e logo depois e chamado o construtor da classe concreta.
Exemplo:
public abstract class ClasseAbstract {
//construtor Default
public ClasseAbstract (){
System.out.println(“Construtor Default da classe abstract.”);
}
}
public class ClasseConcreta extends ClasseAbstract {
//construtor Default
public ClasseAbstract (){
System.out.println(“Construtor Default da classe concreta.”);
}
}
Agora quando for realizado um new ClasseConcreta();
O resultado será :
Construtor Default da classe abstract.
Construtor Default da classe concreta.