Toegankelijkheid van variabelen en functies binnen mijn klassen

Ik heb 2 vragen, maar ze zijn ongeveer hetzelfde (vergelijkbaar?) Probleem.

Eerste vraag:

public class A {

    public void myProcedure() {
        doSomethingA();
    }

    private void doSomethingA() {}

}

public class B extends A {

    @Override
    public void myProcedure() {
        doSomethingB();
       //IT DOESN'T CALL super.myProcedure
    }

    private void doSomethingB() {}

}

public class C extends B {

    @Override
    public void myProcedure() {
       //I need to execute A's myProcedure here
    }

}

Hoe voer ik A 's myProcedure uit, zonder doSomethingA in te stellen op public ?

Tweede vraag:

Ik maak mijn eigen TextBox , er is een variabele genaamd myValue . Nu maak ik een AdvancedTextBox die de code TextBox overneemt, en de AdvancedTextBox moet de variabele myValue gebruiken. Het probleem is, ik wil dat de toekomstige ontwikkelaar zowel TextBox en AdvancedTextBox gebruikt, of overnemen, dat deze geen toegang hebben tot myValue . Is dit mogelijk?

EDIT: Oli Charlesworth and NullUserException ఠ_ఠ tell me to let C inherit A directly (first question). However, there's some cases this can be disaster. For example: A = TextBox, B = AdvancedTextBox, C = NumberAdvancedTextBox, if C inherits A, so C have to do everything that B does again, with some small changes.

0
@OliCharlesworth Ik heb mijn vraag bewerkt (voeg aan het eind informatie toe), om te vertellen dat de casus C niet rechtstreeks van A. zou moeten erven.
toegevoegd de auteur Luke Vo, de bron
Ten eerste: maak het beschermd, niet privé.
toegevoegd de auteur corsiKa, de bron
Ik ben het eens met @OliCharlesworth. Als u de methoden van A vanuit C wilt gebruiken, moet C misschien rechtstreeks van A. erven.
toegevoegd de auteur NullUserException, de bron
Volgens het substitutieprincipe zou een object van het type C zich moeten gedragen als een specialisatie van B . Als u het gedrag terug wilt brengen naar dat van A , betekent dit dat uw hiërarchie onjuist is.
toegevoegd de auteur Oliver Charlesworth, de bron
Oli's punt over de substitutie-principal staat nog steeds. Als een NumberAdvancedTextBox niet kan worden vervangen door een AdvancedTextBox en exact hetzelfde gedrag vertoont, houdt u zich niet aan de principal. Hoymkot's antwoord hieronder is de inhoud van de sleutel - compositie !!! Ik heb zoveel arme ontwerpen gezien als gevolg van de verliefdheid van programmeurs op overerving.
toegevoegd de auteur dsmith, de bron
Ook als ik klasnamen als AdvancedTextBox zie, maak ik me een beetje zorgen. Er is geen exacte semantische betekenis voor het adjectief "Geavanceerd", dus ik ben er vrij zeker van dat het gewoon een greep uit functionaliteit zal zijn. Ik zou het overnemen van een dergelijke klasse niet aanbevelen.
toegevoegd de auteur dsmith, de bron
Ok, dan, als je bij je hiërarchie staat C -> B -> A , dan is het ontwerp van je methoden wat niet juist is. U hebt A.myProcedure in B overschreven waardoor het onmogelijk is om het te bellen vanuit een instantie van C .
toegevoegd de auteur madth3, de bron

3 antwoord

Wat denk je hiervan ...

  • Plaats A en C in hetzelfde pakket en plaats B in een ander pakket.
  • Verwijder "private" uit A.doSomethingA()
  • Geef C een exemplaar van A. (Favor Composition over Inheritance)
  • Omdat C en A in hetzelfde pakket zitten, kan C op elk gewenst moment A.doSomethingA() aanroepen.

Hier is definitie van A

package ac; 

public class A {

    public void myProcedure() {
        doSomethingA();
    }

   void doSomethingA() {}

}

Hier is definitie van B

package b;

public class B extends A {

    @Override
    public void myProcedure() {
        doSomethingB();
       //IT DOESN'T CALL super.myProcedure
    }

    private void doSomethingB() {}

}

Hier is definitie van C

package ac;
// do you really need to extend B? 
public class C {
    A a = new A();

    public void myProcedure() {
        a.doSomethingA(); 
    }

}
2
toegevoegd
C moet B uitbreiden. Maar misschien kan protected het probleem oplossen?
toegevoegd de auteur Luke Vo, de bron

Als een externe module A.myProcedure aanroept, is doSomethingA niet noodzakelijk openbaar. De andere module roept doSomethingA niet rechtstreeks op, en dat is het enige dat ertoe doet. De opzettelijke bedoeling van Java-scope-modifiers is dat ze alleen van toepassing zijn wanneer u een functie DIRECT, niet indirect via een andere functie oproept. Op deze manier kan een klasse een klein aantal openbare functies hebben die de openbare interface definiëren. Dit kan zorgvuldig worden gedocumenteerd en zeer stabiel. Vervolgens kunnen deze openbare functies elk willekeurig aantal privé-functies aanroepen en kunt u deze privé-functies vrijuit schudden, bijvoorbeeld om de prestaties te verbeteren, of om te werken met een nieuwe omgeving, enz. Zonder de openbare interface te hoeven wijzigen.

0
toegevoegd

Omdat doSomethingA een implementatiedetail is. Ik zou het veranderen van een privé in een beschermde om subklassen toe te staan ​​om het direct te bellen.

0
toegevoegd