Lors d'une de mes interviews, on m'a demandé "Si on peut instancier une classe abstraite?"
Ma réponse a été "non, nous ne pouvons pas". Mais, l'intervieweur m'a dit "Faux, nous pouvons."
J'ai argumenté un peu là-dessus. Puis il m'a dit d'essayer moi-même à la maison.
abstract class my {
public void mymethod() {
System.out.print("Abstract");
}
}
class poly {
public static void main(String a[]) {
my m = new my() {};
m.mymethod();
}
}
Ici, je crée une instance de ma classe et j'appelle une méthode de classe abstraite. Quelqu'un peut-il me l'expliquer? Ai-je vraiment tort lors de mon entretien?
B
d'une classe abstraiteA
, pendant la partie de construction d'B
instance, qui consiste à exécuterA
le constructeur de, le type d'exécution de l'objet est en faitA
. Seulement temporaire cependant.Réponses:
Non, vous ne créez pas ici l'instance de votre classe abstraite. Vous créez plutôt une instance d'une sous - classe anonyme de votre classe abstraite. Et puis vous invoquez la méthode sur votre référence de classe abstraite pointant vers l' objet de sous-classe .
Ce comportement est clairement répertorié dans JLS - Section # 15.9.1 : -
Je souligne.
De plus, dans JLS - Section # 12.5 , vous pouvez lire sur le processus de création d'objet . Je vais en citer une déclaration ici: -
Vous pouvez lire la procédure complète sur le lien que j'ai fourni.
Pour voir pratiquement que la classe en cours d'instanciation est une sous- classe anonyme , il vous suffit de compiler vos deux classes. Supposons que vous placiez ces classes dans deux fichiers différents:
My.java:
Poly.java:
Maintenant, compilez vos deux fichiers source:
Maintenant, dans le répertoire où vous avez compilé le code source, vous verrez les fichiers de classe suivants:
Voir cette classe -
Poly$1.class
. Il s'agit du fichier de classe créé par le compilateur correspondant à la sous-classe anonyme que vous avez instanciée à l'aide du code ci-dessous:Il est donc clair qu'il existe une classe différente en cours d'instanciation. C'est juste que, cette classe ne reçoit un nom qu'après compilation par le compilateur.
En général, toutes les sous-classes anonymes de votre classe seront nommées de cette manière:
Ces nombres indiquent l'ordre dans lequel ces classes anonymes apparaissent dans la classe englobante.
la source
instance of
etinstantiating
. Vous instanciez uniquement une classe, tandis que cet objet que vous créez peut être une instance de plusieurs classes en raison de l'héritage.Ce qui précède instancie une classe interne anonyme qui est une sous-classe de la
my
classe abstraite. Ce n'est pas strictement équivalent à l'instanciation de la classe abstraite elle-même. OTOH, chaque instance de sous-classe est une instance de toutes ses super classes et interfaces, donc la plupart des classes abstraites sont en effet instanciées en instanciant une de leurs sous-classes concrètes.Si l'intervieweur vient de dire "mal!" sans expliquer, et a donné cet exemple, comme contre-exemple unique, je pense qu'il ne sait pas de quoi il parle, cependant.
la source
subclassInstance instanceof SuperClass
retournerait vrai, donc l'objet est une instance de la superclasse, ce qui signifie que la superclasse a été instanciée. Mais c'est juste une piqûre sémantique.= my() {};
signifie qu'il ya une mise en œuvre anonyme, pas simple instanciation d'un objet, qui aurait dû être:= my()
. Vous ne pouvez jamais instancier une classe abstraite.la source
Juste des observations que vous pourriez faire:
poly
prolongemy
? C'est inutile ...my.class
,poly.class
etpoly$1.class
Peut-on instancier une classe abstraite?
Non, nous ne pouvons pas. Ce que nous pouvons faire, c'est créer une classe anonyme (c'est le troisième fichier) et l'instancier.
Et une instanciation de super classe?
La super classe abstraite n'est pas instanciée par nous mais par java.
EDIT: lui demander de tester cela
la sortie est:
la source
Serializable s = new Serializable() {};
( ce qui est assez inutile) et si marqué sur votre code donneraitclass my$3
(ou tout ce qui entoure la classe et le nombre)Vous pouvez simplement répondre, en une seule ligne
Mais, l'intervieweur n'est toujours pas d'accord, alors vous pouvez lui dire
Et, selon la classe Anonymous, la classe déclarée et instanciée au même endroit / ligne
Il est donc possible que l'intervieweur s'intéresse à vérifier votre niveau de confiance et vos connaissances sur les POO.
la source
La partie technique a été bien couverte dans les autres réponses, et elle se termine principalement par:
"Il a tort, il ne sait rien, demandez-lui de rejoindre SO et de tout effacer :)"
Je voudrais aborder le fait (qui a été mentionné dans d'autres réponses) que cela pourrait être une question de stress et est un outil important pour de nombreux enquêteurs pour en savoir plus sur vous et comment réagissez-vous aux situations difficiles et inhabituelles. En vous donnant des codes incorrects, il voulait probablement voir si vous vous disputiez. Pour savoir si vous avez la confiance nécessaire pour vous opposer à vos aînés dans des situations similaires à celle-ci.
PS: Je ne sais pas pourquoi mais j'ai le sentiment que l'intervieweur a lu ce post.
la source
Les classes abstraites ne peuvent pas être instanciées, mais elles peuvent être sous-classées. Voir ce lien
Le meilleur exemple est
Bien que la classe Calender ait une méthode abstraite getInstance () , mais quand vous dites
Calendar calc=Calendar.getInstance();
calc fait référence à l'instance de classe de la classe GregorianCalendar comme "GregorianCalendar étend le calendrier "
En fait, le type interne annonymous vous permet de créer une sous-classe sans nom de la classe abstraite et une instance de celle-ci.
la source
Réponse technique
Les classes abstraites ne peuvent pas être instanciées - c'est par définition et par conception.
Du JLS, Chapitre 8. Classes:
Depuis JSE 6 java doc pour Classes.newInstance ():
Vous pouvez, bien sûr, instancier une sous-classe concrète d'une classe abstraite (y compris une sous-classe anonyme) et également effectuer une transtypage d'une référence d'objet en un type abstrait.
Un angle différent à ce sujet - Teamplay & Social Intelligence:
Ce type de malentendu technique se produit fréquemment dans le monde réel lorsque nous traitons de technologies complexes et de spécifications légalistes.
Les «compétences humaines» peuvent être plus importantes ici que les «compétences techniques». Si vous essayez de manière compétitive et agressive de prouver votre côté de l'argument, alors vous pourriez avoir théoriquement raison, mais vous pourriez également faire plus de dégâts en vous battant / en endommageant le "visage" / en créant un ennemi que cela ne vaut. Soyez réconciliant et compréhensif pour résoudre vos différends. Qui sait - peut-être que vous avez "tous les deux raison" mais que vous travaillez avec des significations légèrement différentes pour les termes ??
Qui sait - mais peu probable, il est possible que l'intervieweur ait délibérément introduit un petit conflit / malentendu pour vous mettre dans une situation difficile et voir comment vous vous comportez émotionnellement et socialement. Soyez courtois et constructif avec vos collègues, suivez les conseils des personnes âgées et poursuivez après l'entretien pour résoudre tout problème / malentendu - par e-mail ou appel téléphonique. Montre que vous êtes motivé et soucieux du détail.
la source
C'est un fait bien établi qui ne
abstract class
peut pas être instancié comme tout le monde a répondu.Lorsque le programme définit une classe anonyme, le compilateur crée en fait une nouvelle classe avec un nom différent (a le modèle
EnclosedClassName$n
oùn
est le numéro de classe anonyme)Donc, si vous décompilez cette classe Java, vous trouverez le code ci-dessous:
Ma classe
poly $ 1.class (la classe générée de la "classe anonyme")
ploly.cass
la source
Non, vous ne pouvez pas instancier une classe abstraite. Nous instancions uniquement la classe anonyme. Dans la classe abstraite, nous déclarons des méthodes abstraites et définissons uniquement des méthodes concrètes.
la source
À propos des classes abstraites
Le but d'une classe abstraite est de se comporter comme une base. Dans la hiérarchie d'héritage, vous verrez des classes abstraites vers le haut.
la source
Vous pouvez dire:
nous ne pouvons pas instancier une classe abstraite, mais nous pouvons utiliser un
new
mot clé pour créer une instance de classe anonyme en ajoutant simplement{}
comme corps d'implémentation à la fin de la classe abstraite.la source
L'extension d'une classe ne signifie pas que vous instanciez la classe. En fait, dans votre cas, vous créez une instance de la sous-classe.
Je suis à peu près sûr que les classes abstraites ne permettent pas d'initier. Donc, je dirais non: vous ne pouvez pas instancier une classe abstraite. Mais, vous pouvez l'étendre / l'hériter.
Vous ne pouvez pas instancier directement une classe abstraite. Mais cela ne signifie pas que vous ne pouvez pas obtenir indirectement une instance de classe (pas réellement une instance de classe abstraite d'origine). Je veux dire que vous ne pouvez pas instancier la classe abstraite d'origine, mais vous pouvez:
Vous avez donc accès à toutes les méthodes et propriétés d'une classe abstraite via l'instance de classe dérivée.
la source
Il est impossible d'instancier une classe abstraite. Ce que vous pouvez vraiment faire, a implémenter certaines méthodes courantes dans une classe abstraite et laisser les autres non implémentées (en les déclarant abstraites) et laisser le descendant concret les implémenter en fonction de leurs besoins. Ensuite, vous pouvez créer une usine, qui retourne une instance de cette classe abstraite (en fait son implémenteur). En usine, vous décidez ensuite quel exécuteur choisir. Ceci est connu comme un modèle de conception d'usine:
L'implémenteur concret n'a besoin que d'implémenter les méthodes déclarées comme abstraites, mais aura accès à la logique implémentée dans ces classes dans une classe abstraite, qui ne sont pas déclarées abstraites:
Enfin, l'usine ressemble à ceci:
Le récepteur de AbstractGridManager appellerait les méthodes sur lui et obtiendrait la logique, implémentée dans le descendeur concret (et partiellement dans les méthodes de classe abstraites) sans savoir quelle est l'implémentation concrète qu'il a obtenue. Ceci est également appelé inversion de contrôle ou injection de dépendance.
la source
Non, nous ne pouvons pas créer l'objet de classe abstraite, mais créer la variable de référence de la classe abstraite. La variable de référence est utilisée pour faire référence aux objets des classes dérivées (sous-classes de la classe abstraite)
Voici l'exemple qui illustre ce concept
Ici, nous voyons que nous ne pouvons pas créer l'objet de type Figure mais nous pouvons créer une variable de référence de type Figure. Ici, nous avons créé une variable de référence de type Figure et Figure Variable de référence de classe est utilisée pour faire référence aux objets de classe Rectangle et Triangle.
la source
En fait, nous ne pouvons pas créer directement un objet d'une classe abstraite. Ce que nous créons est une variable de référence d'un appel abstrait. La variable de référence est utilisée pour faire référence à l'objet de la classe qui hérite de la classe abstraite, c'est-à-dire la sous-classe de la classe abstraite.
la source