Perché il metodo del livello di accesso pubblico viene sovrascritto in java?

-2

Questa domanda viene sollevata con un chiarimento richiesto per decidere quando dichiarare un metodo protected o public durante la progettazione della classe di un pacchetto.

Il mio punto è, se è necessario sovrascrivere un metodo di SuperClass , quindi rendere il livello di accesso al metodo come package private o protected in SuperClass ma non dare il livello di accesso public e quindi SubClass inherit SuperClass per sovrascrivere quel metodo.

se public metodo di livello di accesso è sovrascritto in SubClass allora public metodo di livello di accesso è anche diventato un metodo dipendente dall'implementazione in ogni nuovo SubClass progettato, che rompe il concetto di abstraction . Poiché l'utente che utilizza public metodo di accesso al livello addNotify() , dovrebbe sapere che l'implementazione è diversa in awt.Component / awt.Checkbox / awt.Button class, il che significa che non è possibile nascondere i dettagli di implementazione qui. Inoltre, abstract class dovrebbe essere scoperto e progettato per avere solo implementazioni comuni dei suoi metodi concrete subclass , ma è piuttosto strano vedere che abstract class Component{} rompe questa definizione.

Con il livello di accesso assegnato a questo metodo public void addNotify() {} , senza conoscere il significato o il significato di questo metodo, vorrei chiedere,

Diventa difficile decidere il livello di accesso di un metodo durante la progettazione della classe come public o protected ?

Perché vorrei dire che in fase di progettazione qualsiasi metodo sarà public in SuperClass solo quando saranno soddisfatte 2 ragioni:

1) Non ci deve essere la necessità di sovrascrivere questo metodo in SubClass in / out del pacchetto, se si tenta di sovrascrivere SuperClass .

2) Sulla base della firma di qualsiasi metodo di livello public , deve essere sicuro dopo aver preso la decisione che questo metodo può essere pubblicamente disponibile, quindi questo metodo non dovrebbe dipendere dall'implementazione in nessun nuovo SubClass in / out del pacchetto. firma nel senso che, ho reso la mia sotto DList di classe disponibile per eseguire l'aggiornamento sequenziale di DList nel tempo O (n), quindi nessun SubClass deve sovrascrivere il prevNode() metodo di DList class. Questo è rischioso !!! Poiché i puntatori prev/next possono essere manipolati qui con una cattiva codifica. Il principio LSK diventerà sicuro.

   package DList;/* DList.java */ 
   public class DList {
    ......
      public DListNode prevNode(DListNode node) { /* check this signature*/
        if(node.prev != this.sentinel){
            return node.prev;
        }else{
            return null;
        }
      }
    .......
    }
    /* DListNode.java */
    package List;
    public class DListNode {
       public Object item; /* check this */
       protected DListNode prev;
       protected DListNode next;

      DListNode(Object i, DListNode p, DListNode n) {/* check this signature*/
        this.item = i;
        this.prev = p;
        this.next = n;
      }
    }

Quindi

Con l'esperienza del codice java scritto, mi sembra facile decidere uno dei due possibili livelli di accesso di tutto il class es / interface design all'interno di un pacchetto.

sembra facile decidere mentre introduce la firma di nuovi metodi, se un metodo deve avere il livello di accesso private se un metodo deve avere il livello di accesso package private

Se capisco la domanda seguente, sarebbe facile decidere quando un metodo è protected o public . 1) Perché java consente di sovrascrivere i metodi di livello di accesso public ? Perché è difficile per me decidere quando rendere il mio metodo protected , nonostante io sappia che public è più visibile di protected tra i pacchetti. Si deve prevedere il costo / la conseguenza dell'introduzione di una nuova relazione di ereditarietà prima di assegnare il livello di accesso di protected al metodo del proprio attuale modello di classe.

2) Posso conoscere la risorsa giusta per imparare quando un metodo può essere protected ?

Nota: sono un principiante Java che attualmente comprende l'astrazione / incapsulamento / ereditarietà / polimorfismo e sta per imparare "pacchetto e accesso agli specificatori"

    
posta overexchange 13.12.2014 - 11:24
fonte

2 risposte

2

La risposta alla tua ultima domanda è che verrà da te con esperienza. Ma in sostanza, non inizi con l'aggiunta di nuovi metodi e chiedendoti quale parola chiave usare. Inizi a pensare a quali responsabilità avrà la classe, cosa promette che farà alle classi intorno ad essa. Ogni classe gestisce alcuni dettagli in modo che le altre classi non debbano preoccuparsi di loro, e puoi pensare ad esso come un mucchio di contratti. I modificatori di accesso sono gli strumenti che usi per dichiarare (e in un certo senso imporre) quei contratti.

La risposta alla tua altra domanda è che public , protected e private riguardano l'accessibilità, non l'abilità di sovrascrittura. La parola chiave Java che controlla se qualcosa può essere sovrascritto in una sottoclasse è final . Quindi se vuoi che un membro sia accessibile ma non sovrascrivibile, dichiaralo public final . Non c'è modo di fare il contrario (sovrascrivibile in una sottoclasse ma non accessibile da una sottoclasse) perché non ha senso sovrascrivere qualcosa che non si può vedere.

    
risposta data 13.12.2014 - 15:45
fonte
3

if public access level method is also overridden in SubClass then public access level method has also become an implementation dependent method in every new SubClass designed, which breaks Encapsulation. Because user using public level access method addNotify(), should know that it's implementation is different in awt.Component/ awt.Checkbox/awt.Button class, which means hiding of implementation details not ensured here.

Le parti in grassetto non dovrebbero essere vere per la maggior parte dei casi. Infatti, se devi conoscere il sottotipo di un oggetto prima di usarlo, è un segno che le tue astrazioni non sono abbastanza buone per nascondere i dettagli di implementazione ( che perde ). Questo è ulteriormente ampliato dal Principio di sostituzione di Liskov (LSP), che dice che dovresti essere in grado di scrivere il tuo codice circa l'uso di una superclasse / interfaccia, e il suo comportamento è invariato se e quando ti viene dato qualsiasi oggetto di una sottoclasse.

Quindi per rispondere alle tue domande:

  1. Java ti permette di sovrascrivere i metodi pubblici perché non c'è nulla di sbagliato nel farlo. Poiché alcune persone potrebbero abusare di uno strumento, non significa che lo strumento sia cattivo. Segui l'LSP e prova a mantenere le tue astrazioni chiuse a sufficienza e non dovrai preoccuparti di estendere il comportamento pubblico di un oggetto in futuro.

  2. Dato che hai già definito tutti i metodi pubblici e stai semplicemente scegliendo se mantenere privati o protetti i metodi interni, puoi utilizzare la seguente regola: Lasciare tutto privato, fino a quando non è necessario sottoclasse / sovrascrittura esiste, quindi trasformarlo in protetto. Questa è una buona linea guida, soprattutto perché non possiamo prevedere il futuro e si può sprecare una notevole quantità di tempo nel cercare di rendere tutto estensibile solo per scoprire che ci sono stati solo pochi casi in cui è stato utile. Se si desidera leggere le migliori linee guida per consentire l'estensibilità futura, è possibile leggere i materiali attorno alle applicazioni di Open-Closed Principle (OCP). Attenzione però, è uno dei principi SOLID più difficili da applicare, a meno che non si veda il futuro ( o hai abbastanza esperienza per fare supposizioni molto affidabili).

In generale, ti consiglio di leggere i principi SOLID, con particolare attenzione a LSP e OCP, perché si adattano ai tuoi problemi attuali. Inoltre, consiglierei di leggere su Composition vs. Inheritance, poiché a volte è meglio non estendere affatto le classi, ma piuttosto comporle di altri oggetti intercambiabili.

    
risposta data 13.12.2014 - 15:51
fonte

Leggi altre domande sui tag