Durante uma das minhas entrevistas, perguntaram-me "Se podemos instanciar uma aula abstrata?"
Minha resposta foi "Não. Não podemos". Mas, o entrevistador me disse: "Errado, nós podemos".
Eu argumentei um pouco sobre isso. Então ele me disse para tentar fazer isso sozinho em casa.
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
Aqui, estou criando uma instância da minha classe e chamando o método da classe abstrata. Alguém por favor pode me explicar isso? Eu estava realmente errado durante a minha entrevista?
B
de uma abstrataA
, durante a parte da construção daB
instância, que consisteA
no construtor da execução, o tipo de tempo de execução do objeto é realmenteA
. Apenas temporário no entanto.Respostas:
Não, você não está criando a instância da sua classe abstrata aqui. Em vez disso, você está criando uma instância de uma subclasse anônima da sua classe abstrata. E então você está invocando o método em sua referência de classe abstrata apontando para objeto da subclasse .
Esse comportamento está claramente listado na JLS - Seção # 15.9.1 : -
Ênfase minha.
Além disso, na JLS - Seção # 12.5 , você pode ler sobre o Processo de Criação de Objetos . Vou citar uma declaração a partir daqui:
Você pode ler sobre o procedimento completo no link que forneci.
Para ver praticamente que a classe que está sendo instanciada é uma subclasse anônima , basta compilar as duas classes. Suponha que você coloque essas classes em dois arquivos diferentes:
My.java:
Poly.java:
Agora, compile seus arquivos de origem:
Agora, no diretório em que você compilou o código-fonte, você verá os seguintes arquivos de classe:
Veja essa classe -
Poly$1.class
. É o arquivo de classe criado pelo compilador correspondente à subclasse anônima que você instanciaram usando o código abaixo:Portanto, fica claro que há uma classe diferente sendo instanciada. Só que, essa classe recebe um nome somente após a compilação pelo compilador.
Em geral, todas as subclasses anônimas da sua classe serão nomeadas desta maneira:
Esses números indicam a ordem em que essas classes anônimas aparecem na classe anexa.
fonte
instance of
einstantiating
. Você instancia apenas uma classe, enquanto esse objeto que você cria pode ser uma instância de várias classes devido à herança.O exemplo acima instancia uma classe interna anônima, que é uma subclasse da
my
classe abstrata. Não é estritamente equivalente a instanciar a própria classe abstrata. OTOH, toda instância de subclasse é uma instância de todas as suas superclasses e interfaces; portanto, a maioria das classes abstratas é realmente instanciada instanciando uma de suas subclasses concretas.Se o entrevistador apenas disser "errado!" sem explicar, e deu este exemplo, como um contra-exemplo único, acho que ele não sabe do que está falando.
fonte
subclassInstance instanceof SuperClass
retornaria true, portanto o objeto é uma instância da superclasse, o que significa que a superclasse foi instanciada. Mas isso é apenas nitpicking semântico.= my() {};
significa que há uma implementação anônimo, não é simples instanciação de um objeto, que deveria ter sido:= my()
. Você nunca pode instanciar uma classe abstrata.fonte
Apenas observações que você pode fazer:
poly
se estendemy
? Isso é inútil ...my.class
,poly.class
epoly$1.class
Podemos instanciar uma classe abstrata?
Não, não podemos. O que podemos fazer é criar uma classe anônima (esse é o terceiro arquivo) e instancia-la.
Que tal uma instancia super classe?
A superclasse abstrata não é instanciada por nós, mas por java.
EDIT: Peça a ele para testar isso
saída é:
fonte
Serializable s = new Serializable() {};
(o que é bastante inútil) e se marcado em seu código poderia darclass my$3
(ou o que quer encerrar classe e número)Você pode simplesmente responder, em apenas uma linha
Mas, o entrevistador ainda não concorda, então você pode dizer a ele / ela
E, de acordo com a classe Anonymous, a classe declarada e instanciada no mesmo local / linha
Portanto, é possível que o entrevistador esteja interessado em verificar seu nível de confiança e o quanto você sabe sobre os OOPs.
fonte
A parte técnica foi bem abordada nas outras respostas e termina principalmente em:
"Ele está errado, ele não sabe nada, peça a ele para se juntar ao SO e esclarecer tudo isso :)"
Gostaria de abordar o fato (que foi mencionado em outras respostas) de que essa pode ser uma questão de estresse e é uma ferramenta importante para muitos entrevistadores saberem mais sobre você e como você reage a situações difíceis e incomuns. Ao fornecer códigos incorretos, ele provavelmente queria ver se você argumentou de volta. Saber se você tem confiança para enfrentar seus idosos em situações semelhantes a essa.
PS: Não sei por que, mas sinto que o entrevistador leu este post.
fonte
As classes abstratas não podem ser instanciadas, mas podem ser subclassificadas. Veja este link
O melhor exemplo é
Embora a classe Calender tenha um método abstrato getInstance () , mas quando você diz
Calendar calc=Calendar.getInstance();
calc está se referindo à instância da classe GregorianCalendar como "GregorianCalendar estende o calendário "
Infact tipo interior annonymous permite criar uma subclasse não-nome da classe abstrata e uma instância desta.
fonte
Resposta técnica
Classes abstratas não podem ser instanciadas - isto é por definição e design.
No JLS, capítulo 8. Classes:
No JSE 6, o java doc para Classes.newInstance ():
Obviamente, é possível instanciar uma subclasse concreta de uma classe abstrata (incluindo uma subclasse anônima) e também executar uma conversão de tipo de uma referência de objeto a um tipo abstrato.
Um ângulo diferente sobre isso - Teamplay e inteligência social:
Esse tipo de mal-entendido técnico acontece com frequência no mundo real quando lidamos com tecnologias complexas e especificações legalistas.
As "habilidades das pessoas" podem ser mais importantes aqui do que as "habilidades técnicas". Se competitiva e agressivamente tentar provar o seu lado do argumento, você pode estar teoricamente certo, mas também poderá causar mais dano ao ter uma "face" brutal / prejudicial / criar um inimigo do que vale a pena. Seja reconciliatório e compreensivo ao resolver suas diferenças. Quem sabe - talvez você esteja "certo", mas trabalhando com significados ligeiramente diferentes para termos?
Quem sabe - embora não seja provável, é possível que o entrevistador tenha introduzido deliberadamente um pequeno conflito / mal-entendido para colocá-lo em uma situação desafiadora e ver como você se comporta emocional e socialmente. Seja gentil e construtivo com os colegas, siga os conselhos dos idosos e siga após a entrevista para resolver qualquer desafio / mal-entendido - por e-mail ou telefonema. Mostra que você está motivado e detalhista.
fonte
É um fato bem estabelecido que não
abstract class
pode ser instanciado, pois todos responderam.Quando o programa define classe anônima, o compilador realmente cria uma nova classe com nome diferente (tem o padrão
EnclosedClassName$n
em quen
é o número da classe anônima)Portanto, se você descompilar essa classe Java, encontrará o código abaixo:
minha classe
poly $ 1.class (a classe gerada da "classe anônima")
ploly.cass
fonte
Não, você não pode instanciar uma classe abstrata. Instanciamos apenas uma classe anônima. Na classe abstrata, declaramos métodos abstratos e definimos apenas métodos concretos.
fonte
Sobre Classes Abstratas
O objetivo de uma classe abstrata é se comportar como uma base. Na hierarquia de herança, você verá classes abstratas no topo.
fonte
Você pode dizer:
não podemos instanciar uma classe abstrata, mas podemos usar a
new
palavra-chave para criar uma instância de classe anônima apenas adicionando{}
como corpo do implemento no final da classe abstrata.fonte
Estender uma classe não significa que você está instanciando a classe. Na verdade, no seu caso, você está criando uma instância da subclasse.
Tenho certeza de que as classes abstratas não permitem a iniciação. Então, eu diria que não: você não pode instanciar uma classe abstrata. Mas você pode estendê-lo / herdá-lo.
Você não pode instanciar diretamente uma classe abstrata. Mas isso não significa que você não pode obter uma instância da classe (e não uma instância da classe abstrata original) indiretamente. Quero dizer, você não pode instanciar a classe abstrata orginial, mas pode:
Portanto, você obtém acesso a todos os métodos e propriedades em uma classe abstrata por meio da instância da classe derivada.
fonte
É impossível instanciar uma classe abstrata. O que você realmente pode fazer, implementou alguns métodos comuns em uma classe abstrata e deixou outros não implementados (declarando-os abstratos) e deixou o descendente concreto implementá-los, dependendo de suas necessidades. Então você pode criar uma fábrica, que retorna uma instância dessa classe abstrata (na verdade, seu implementador). Na fábrica, você decide qual implementador escolher. Isso é conhecido como padrão de design de fábrica:
O implementador concreto precisa implementar apenas os métodos declarados como abstratos, mas terá acesso à lógica implementada nessas classes em uma classe abstrata, que não é declarada abstrata:
Finalmente, a fábrica se parece com isso:
O receptor do AbstractGridManager chamaria os métodos e obteria a lógica, implementada no descendente concreto (e parcialmente nos métodos da classe abstrata) sem saber qual é a implementação concreta que ele obteve. Isso também é conhecido como inversão do controle ou injeção de dependência.
fonte
Não, não podemos criar o objeto da classe abstrata, mas criar a variável de referência da classe abstrata. A variável de referência é usada para se referir aos objetos de classes derivadas (subclasses da classe Abstract)
Aqui está o exemplo que ilustra esse conceito
Aqui vemos que não podemos criar o objeto do tipo Figura, mas podemos criar uma variável de referência do tipo Figura. Aqui, criamos uma variável de referência do tipo Figura e a variável de referência de classe de figura é usada para se referir aos objetos de retângulo e triângulo de classe.
fonte
Na verdade, não podemos criar diretamente um objeto de uma classe abstrata. O que criamos é uma variável de referência de uma chamada abstrata. A variável de referência é usada para Referir-se ao objeto da classe que herda a classe Abstract, ou seja, a subclasse da classe abstract.
fonte