Java-Zugriffsmodifikatoren und überschreibende Methoden

Warum gibt Java an, dass der Zugriffsspezifizierer für eine überschreibende Methode mehr, aber nicht weniger Zugriff als die überschriebene Methode zulassen kann? Zum Beispiel kann eine geschützte Instanzmethode in der Oberklasse in der Unterklasse öffentlich, aber nicht privat gemacht werden.

Solutions Collecting From Web of "Java-Zugriffsmodifikatoren und überschreibende Methoden"

Es ist ein grundlegendes Prinzip in OOP: Die Kindklasse ist eine vollwertige Instanz der Elternklasse und muss daher mindestens die gleiche Schnittstelle wie die Elternklasse aufweisen. Geschützte / öffentliche Dinge weniger sichtbar zu machen, würde diese Idee verletzen; Sie könnten untergeordnete classn als Instanzen der übergeordneten class unbrauchbar machen.

Stellen Sie sich diese zwei classn vor:

 public class Animal { public String getName() { return this.name; } } public class Lion extends Animal { private String getName() { return this.name; } } 

Ich könnte diesen Code schreiben:

 Animal lion = new Lion(); System.out.println( lion.getName() ); 

Und es müsste gültig sein, denn bei Animal ist die Methode getName () öffentlich, auch wenn sie auf Lion privat gemacht wurde. Es ist also nicht möglich, Dinge in Unterklassen weniger sichtbar zu machen, da Sie, sobald Sie eine Superklassenreferenz haben, auf dieses Zeug zugreifen könnten.

Weil es komisch wäre:

 class A { public void blah() {} } class B extends A { private void blah() {} } B b = new B(); A a = b; b.blah(); // Can't do it! a.blah(); // Can do it, even though it's the same object! 

Nehmen Sie ein Beispiel unten

  class Person{ public void display(){ //some operation } } class Employee extends Person{ private void display(){ //some operation } } 

Ein typisches Überschreiben geschieht im folgenden Fall

 Person p=new Employee(); 

Hier ist p die Objektreferenz mit dem Typ Person ( Superklasse ), wenn wir p.display () aufrufen. Da der Zugriffsmodifikator restriktiver ist, kann der Objektverweis p nicht auf das untergeordnete Objekt vom Typ Employee zugreifen

Spät zur Party, aber ich möchte noch eine weitere Problematik hinzufügen, die sich auf das Überschreiben bezieht: Die überschreibende Methode muss weniger (oder dieselbe Ebene von) throwable Ausnahme als die überschriebene Methode erlauben; sogar nichts, das man casting könnte.

Liskov-Substitutionsprinzip kann das auch erklären:

 interface Actionable { void action() throws DislocationException; } public class Actor implements Actionable { @Override public void action() throws DislocationException { //.... } } public class Stuntman implements Actionable { @Override // this will cause compiler error public void action() throws DislocationException, DeathException { //.... } } // legacy code to use Actionable try { Actionable actor = new Actor(); // this cannot be replaced by a Stuntman, // or it may break the try/catch block actor.action(); } catch (DislocationException exc) { // Do something else } 

Oben, die überholte Methode hat sich verpflichtet, dass im schlimmsten Fall die DislocationException, nicht mehr (ein Arzt ist am Drehort erforderlich) casting wird. Also darf die übergeordnete Methode das nicht brechen, indem mehr DeathException hinzugefügt wird (oder ein Krankenwagen ist ein Muss)

Ich nenne oft die übergeordnete Regel “[kann sein] mehr Zugang [Ebene], [aber] weniger Ausnahme”

Da eine Unterklasse eine Spezialisierung der Oberklasse ist oder anders ausgedrückt, handelt es sich um eine Erweiterung der Oberklasse.

Stellen Sie sich zum Beispiel die Methode toString vor. Alle Java-Objekte haben es, weil das Objekt der class es hat. Stellen Sie sich vor, Sie könnten eine class mit der Methode toString private definieren. Sie behandeln dann nicht mehr alle Objekte gleich. Zum Beispiel könntest du das nicht mehr so ​​sicher machen:

for (Object obj : collection) System.out.println(obj);

Nun, in Bezug auf den speziellen Fall, den Sie erwähnt haben, wie genau würde Java das handhaben? Wenn die Unterklasse eine public / protected-Methode privat gemacht hat, was sollte dann die JVM tun, wenn diese Methode für eine Instanz der Unterklasse aufgerufen wird? Ehre die Private und rufe die Superklassen-Implementierung auf? Außerdem brechen Sie den Vertrag, der von der Oberklasse festgelegt wurde, wenn Sie plötzlich sagen: “Niemand kann auf diese Methode zugreifen, obwohl der Vertrag ursprünglich gesagt hat.”