2012-01-27 3 views
0

J'ai appris que nous ne pouvons pas instancier une classe abstraite. Mais aujourd'hui, j'ai testé quelques codes et je me sens confus à ce sujet.créer un objet d'une classe abstraite! = Instancier la classe abstraite?

package MainPackage; 

abstract class abstractClass { 
    abstract abstractClass a_function(); 
} 

public class Src { 
    abstractClass m; 
    public abstractClass abstractClassTest() { 
     return m.a_function(); 
    } 
    public static void main(String args[]) { 
     System.out.println("Hello world!"); 
    } 
} 

Ici je crée une classe abstraite AbstractClass et retour dans la fonction abstractClassTest(). Et il est compilé avec succès sans erreurs! IMO avant de retourner quelque chose, l'ordinateur devrait créer un objet de ce type. Et ici, il devrait créer un objet de abstractClass avant retourner m.function(), que je ne comprends pas. Je pense que nous ne pouvons pas instancier une classe abstraite signifie que nous ne pouvons pas créer un objet d'une classe abstraite ou nous cant nouvelle classe (par exemple. abstractClass m = new abstractClass() is illegal). Mais à partir des codes ci-dessus, il semble que nous pouvons créer un objet d'une classe abstraite. comment peut-il réaliser? Pour le code abstractClass m, que fait l'ordinateur quand il voit le code? Nous ne pouvons pas dire que java a instancié la classe abstraite m pour le code abstractClass m? et si java instancie la classe abstractClass, comment peut-il retourner l'objet de abstractClass dans le code abstract abstractClass a_function();?

+0

Vous n'êtes pas *** instancier *** une classe abstraite, en utilisant simplement sa référence. – Bhushan

+0

Notez que votre code * n'instancie aucun objet abstractclass. Si vous deviez créer une sous-classe de abstractclass, vous pourriez l'instancier (abstractClass m = new childClass (...)) puis m.a_function serait valide. –

+0

Comme vous le faites remarquer, vous ne pouvez pas "nouveau" une classe abstraite. Votre code n'a pas de "nouveau" n'importe où - alors où serait le problème? – yshavit

Répondre

5

Oui, devrait compiler sans erreurs. Il lancerait un NullPointerException à l'exécution si vous avez déjà appelé abstractClassTest, car vous n'initialisez jamais la variable m pour faire référence à une instance réelle. Pour ce faire, vous devez créer une classe concrète qui sous-classe votre classe abstraite.

Par exemple:

public class ConcreteClass extends AbstractClass { 
    @Override AbstractClass a_function() { 
     return this; 
    } 
} 

public class Src { 
    private AbstractClass m = new ConcreteClass(); 

    public AbstractClass abstractClassTest() { 
     return m.a_function(); 
    } 
    public static void main(String args[]) { 
     new Src().abstractClassTest(); 
    } 
} 

Notez que rien dans votre code crée une instance de la classe abstraite. Ce n'est pas parce que vous avez une variable de ce type qu'un objet de ce type a été créé.

+0

Si vous essayez d'initialiser la variable directement avec une instance de la classe abstraite, vous obtenez une erreur de compilation. –

+3

@SpencerKormos: Oui, l'OP semble déjà le savoir. –

+0

Juste marquage pour l'exhaustivité. :-) –

0

Vous ne pouvez pas directement instancier une classe abstraite, et votre code ne le fait pas réellement. Ce que vous avez est simplement une référence à une sous-classe ou à une autre de votre classe abstraite, et quand vous venez d'instancier 'm', vous devez fournir une sous-classe concrète réelle.

Vous obtenez un modèle similaire avec des interfaces. Il est tout à fait légal d'écrire, par exemple:

List m; 
... 
m.size(); 

mais quand vous êtes venu à instancier, vous le ferait avec une sous-classe mise en œuvre, par exemple:

List m; 
... 
m = new ArrayList(); 
... 
m.size(); 

Remarquez comment à l'instanciation, nous utilisons ArrayList, pas List (qui est juste l'interface).

1

m n'est jamais affecté et vous n'essayez jamais d'instancier une nouvelle classe abstraite avec le nouveau mot-clé. Si votre code arrivait à abstractClassTest, vous obtiendriez simplement une exception de pointeur nul. Je pense que vous pourriez mélanger en déclarant une variable et en lui donnant une valeur.