2009-05-03 5 views

Répondre

14

va créer des instances, juste des instances d'une classe dérivée. Ces classes dérivées auront toujours besoin d'appeler des constructeurs, et peuvent toujours appeler des membres de la classe abstraite - qui peuvent à leur tour utiliser des membres privés.

Voici un exemple (pas un terriblement utile, mais juste pour montrer l'idée de base ...)

public abstract class NamedObject 
{ 
    private final String name = name; 

    protected NamedObject(String name) 
    { 
     this.name = name; 
    } 

    public String getName() 
    { 
     return name; 
    } 
} 

public class Computer extends NamedObject 
{ 
    private final int processorSpeed; 

    public Computer(String name, int processorSpeed) 
    { 
     super(name); // See, the constructor is useful 
     this.processorSpeed = processorSpeed; 
    } 

    public String toString() 
    { 
     return getName() + " (" + processorSpeed + ")"; 
    } 
} 

Je ne peux pas dire que j'écris des classes abstraites qui souvent, préférant généralement composition l'héritage, mais quand je le crée, j'utilise certainement des constructeurs et des membres privés.

3

Les classes abstraites fournissent une implémentation partielle de certaines interfaces. Il est parfaitement raisonnable de considérer que vous pourriez vouloir fournir une partie de cette implémentation et empêcher le code client (sous-classes concrètes) d'accéder aux spécificités - c'est-à-dire une extension du principe d'encapsulation. Le fait de marquer certains membres comme étant privés force la classe héritière à appeler des méthodes protégées pour accéder à cette implémentation partielle; fournir un constructeur permet aux sous-classes d'initialiser l'état encapsulé du parent pendant leur propre construction.

1

Contrairement à une interface, une classe abstraite qui définit des champs de données est en fait instanciée dans le sens où ces champs de données sont alloués. C'est juste qu'ils ne sont jamais instanciés par eux-mêmes, ils sont instanciés dans le cadre de quelque chose de plus grand - la sous-classe. Donc, quand la sous-classe est construite, le supertype est également construit, c'est pourquoi vous auriez besoin d'un constructeur.

Selon votre hiérarchie, votre classe abstraite peut avoir une signification et un état. Par exemple, si votre candidature est une école, vous pouvez avoir la notion d'une personne (qui a un nom et un nom de domaine secondaire), mais vous auriez des sous-types différents pour les étudiants et pour les enseignants. Étant donné que les deux types de personnes partagent certaines structures d'état (nom et SSN), les deux classes étendent la classe Person. Mais vous ne pourriez jamais simplement instancier une personne directement.

0

En plus de la réponse de Jon, je voudrais mentionner que les classes abstraites vont encore bien avec la composition, si vous gardez l'arbre de la sous-classe peu profonde. C'est à dire. C'est génial pour fournir une classe de base commune pour quelques objets étroitement liés, mais pas pour créer un arbre gigantesque de sous-classes.

0

Pourquoi avez-vous besoin de cours privés? Je pense que vous confondez des classes abstraites avec des interfaces. Contrairement aux interfaces, les classes abstraites peuvent contenir des fonctionnalités. Par exemple:

public class AbstractBase{ 
    private int num; 

    public AbstractBase(int number){ 
     this->num = number; 
    } 

    public int method(){ 
     return (this->num * this->templateMethod()); 
    } 

    public abstract int templateMethod(); 
} 

public class ConcreteDerived étend AbstractBase {

public ConcreteDerived(){ 
    super(4); 
} 

public int templateMethod(){ 
    return number; //number is the result of some calculation 
} 

}

Dans cet exemple, jamais instancier explicitement vous en aurez AbstractBase, mais en déclarant les membres et les constructeurs, vous pouvez personnaliser la fonctionnalité de vos classes (c'est ce qu'on appelle la méthode de modèle).

0

En supposant que vous faites du code ad hoc ou du prototypage, vous instanciez des classes abstraites (ou peut-être même des interfaces) de temps en temps.On les appelle les classes internes anonymes (one, two) et ressemblent à ceci:

// you have this... 
public abstract class SomeClass { 
    public abstract String returnAString(); 
} 

// ...and this... 
public class OtherClass { 
    public void operate(SomeClass c) { 
     System.out.println(c.returnAString()); 
    } 
} 

// ...so you do this:  
OtherClass oc = new OtherClass(); 
// this is one of the reasons why you need to specify a constructor 
oc.operate(new SomeClass() { 
    @Override 
    public String returnAString() { 
     return "I'm an anonymous inner class!"; 
    } 
}); 

Cet exemple est bien sûr tout à fait superflu mais devrait exposer le point. Certains cadres existants s'appuient même sur l'utilisation intensive de ce comportement, à savoir Apache Wicket au moins.

Questions connexes