web-dev-qa-db-fra.com

Java comment remplacer la méthode facultative dans la classe abstraite?

Disons que nous avons une classe de base:

public abstract class BaseFragment extends Fragment {
    ...
    protected abstract boolean postExec();
    ...
}

Et puis dérivez-en pour avoir d'autres classes (par exemple Fragment_Movie, Fragment_Weather ...)

public class Fragment_Music extends BaseFragment{
    @Override
    protected boolean postExec() {
        return false;
    } 
}

Cependant, lors de l'ajout d'une nouvelle méthode à la classe de base:

public abstract class BaseFragment extends Fragment {
    ...
    protected abstract boolean postExec();
    protected abstract boolean parseFileUrls();
    ...
}

Eclipse affiche instantanément une erreur demandant d'implémenter cette nouvelle méthode dans les classes déjà dérivées.

Y a-t-il lieu d'ajouter une méthode abstraite "par défaut" dans la classe de base, afin qu'elle ne montre pas d'erreur même si nous ne l'implémentons pas dans la classe dérivée? (car il faudrait beaucoup de temps pour corriger chaque classe dérivée chaque fois que la classe de base ajoute une nouvelle méthode.)

19
markbse

La solution la plus simple serait d'ajouter la méthode avec une implémentation tronquée. Le déclarer abstrait nécessite extensions non abstraites pour implémenter la méthode.

Faire quelque chose comme ça faciliterait vos problèmes de compilation, mais cela lèvera évidemment des exceptions lorsqu'il est utilisé sans redéfinir:

public abstract class BaseFragment extends Fragment {
    protected boolean doSomethingNew() {
        throw new NotImplementedException("method not overridden");
    }
}
35
akaIDIOT

Seule la classe abstraite (y compris l'interface) ne devrait pas déclarer TOUTES les méthodes de sa classe de base.

Ainsi, par exemple, une interface ou une classe abstraite étendant une classe de base ou impliquant une interface ne doit pas déclarer toutes les méthodes. La mise en œuvre de la méthode non mise en œuvre sera le travail de la première sous-classe de béton plus profond.

Donc, pour votre problème, vous pourriez éventuellement utiliser la composition sur l'héritage en ajoutant le collaborateur (contenant votre nouvelle méthode commune) comme champ protégé de votre classe de base.

Ainsi, pas besoin d'implémenter rien dans vos classes concrètes et de permettre à celles-ci d'utiliser la méthode du collaborateur dans une méthode de sous-classe appropriée.

Vous pouvez être intéressé par le Bridge pattern dont l'objectif est (de wikipedia):

Le modèle de pont est un modèle de conception utilisé en génie logiciel qui est destiné à "découpler une abstraction de sa mise en œuvre afin que les deux puissent varier indépendamment"

2
Mik378

Les méthodes abstraites ont pour but de forcer vous à les implémenter.

Si vous ajoutez une méthode abstraite dans votre superclasse, vous devez refactoriser votre code et fournir une implémentation; votre programme sera incohérent même avec les implémentations par défaut - que faire si vous devez renvoyer un type personnalisé? Je prendrais mon temps pour fournir une implémentation appropriée, car je devrai probablement appeler de telles méthodes si je les ai ajoutées.

0
moonwave99

Vous pouvez dériver une nouvelle classe abstraite avec la nouvelle méthode abstraite de votre classe de base. Dérivez des classes concrètes qui devraient avoir la nouvelle méthode de cette nouvelle classe et d'autres de l'ancienne classe de base.

0
jpstrube