2017-01-30 5 views
2

Si j'ai une superclasse de classe et une sous-classe de sous-classe, et que certaines fonctions de la sous-classe sont légèrement différentes, est-ce une mauvaise habitude de surcharger l'original, d'appeler super?Est-ce une mauvaise pratique de remplacer une fonction uniquement pour ajouter un peu de fonctionnalité en appelant super?

Par exemple: (code pseudo)

public class BaseClass{ 
    int fooA(); 
    int fooB(); 
    int fooC(); 
} 

public class SubClass extends BaseClass{ 
    @Override 
    int fooB(){ 
     int temp = super.fooB(); 
     temp += 1; 
     return temp; 
    } 

    @Override 
    int fooC(){ 
     System.out.println("I'm doing something extra in fooC!"); 
     return super.fooC(); 
    } 
} 

J'essaie d'éviter la duplication de code, mais je me sens un peu comme si je fais quelque chose de mal ou d'oublier des trucs POO de base, donc je pensais que je demandais si c'était une mauvaise pratique. Cela fait un moment que j'ai fait l'héritage; merci pour tout aperçu.

+1

composition préférerons héritage. – Kayaman

+1

@Kayaman Vous ne pouvez pas simplement dire "Préférez la composition par héritage" comme c'est toujours vrai. Dans certains cas, la composition sera plus appropriée que l'héritage et dans d'autres cas, l'héritage sera plus approprié que la composition. –

+1

* Ça fait longtemps que j'ai hérité *. :) – CKing

Répondre

2

Au lieu de vous héritant pouvez effectuer les opérations suivantes:

public class SubClass implements MyInterface { 
    private MyInterfaceBasicImpl base; 

    int fooB(){ 
     int temp = base.fooB(); 
     temp += 1; 
     return temp; 
    } 

    int fooC(){ 
     System.out.println("I'm doing something using in fooC in base object!"); 
     return base.fooC(); 
    } 
} 

Il est un exemple facile de Composition modèle. Comme il n'y a pas d'héritage multiple dans Java il gardera votre code Ouvert pour des améliorations.

+0

Si je veux que SubClass ait un constructeur similaire (ou le même) que la classe de base, je devrai en hériter, n'est-ce pas? (Je sais que je n'ai pas mis cela dans ma question initiale, mais en regardant mon code, cette mise en garde est apparue).Si je me souviens bien, je devrais opter pour un combo d'une classe abstraite et d'une interface. Merci pour les rafraîchissements. – GuitarStrum

+0

Dans le nouveau constructeur, vous pouvez construire l'objet sur lequel vous conservez la référence. – xenteros

1

La capacité d'une sous-classe de passer outre un procédé permet à une classe de hériter d'une superclasse dont le comportement est « suffisamment proche », puis à modifier le comportement selon le besoin. La méthode de remplacement a le même nom, nombre et type de paramètres, et le type de retour en tant que méthode que remplace. Une méthode de remplacement peut également renvoyer un sous-type du type renvoyé par la méthode substituée. Ce sous-type est appelé un type de retour covariant .

Espérons que cela apporte une réponse à votre question.

https://docs.oracle.com/javase/tutorial/java/IandI/override.html

0

Vous pouvez faire ce que vous proposez, est une option. Mais, que se passe-t-il si vous avez par exemple 3 classes qui font la même chose? Vous répétez encore le code et la logique, parce que dans chacun d'eux, vous appelez super. Dans ce cas, vous pouvez implémenter un modèle de méthode de modèle. Si vous n'avez pas lu à ce sujet, cela signifie définir une méthode dans la super classe comme abstraite, l'utiliser là et ensuite la définir dans les sous-classes. Suite à votre exemple, il pourrait ressembler à ceci:

public class BaseClass{ 
    int fooA(); 
    int fooB(); 
    int fooC(){ 
    //here goes the common logic; 
    this.printWhatItHasToPrint(); 
    } 
    void printWhatItHasToPrint() {}; //if the class is abstract you may define it as abstract 
} 

public class SubClass1 extends BaseClass{ 
    @Override 
    int fooB(){ 
     int temp = super.fooB(); 
     temp += 1; 
     return temp; 
    } 

    @Override 
    void printWhatItHasToPrint(){ 
     System.out.println("I'm doing something extra in fooC!"); 
    } 
} 

public class SubClass2 extends BaseClass{ 

    @Override 
    void printWhatItHasToPrint(){ 
     System.out.println("I'm doing something extra in fooC, and I'm another class!"); 
    } 
} 
0

Je pense que ce serait peut-être l'approche correcte, mais de mon expérience, il est plus lisible et pratique pour faire une classe abstraite avec des fonctions communes mises en œuvre et ensuite deux sous-classes à étendre afin de mettre en œuvre les différentes fonctions, comme ça:

public abstract class BaseClass { 
    public void fooA() { 
     System.out.println("Some common function"); 
    } 

    public void fooB() { 
     System.out.println("Another common function"); 
    } 

    public abstract int fooC(); 
} 

public class SubClass1 extends BaseClass { 
    @Override 
    public int fooC() { 
     return 0; 
    } 
} 

public class SubClass1 extends BaseClass { 
    @Override 
    public int fooC() { 
     return 1; 
    } 
} 

de cette façon, il sera beaucoup plus facile de naviguer à travers les grands projets et se sent plus naturel