modyfikatory dostępu java i metody nadpisywania

Dlaczego Java określa, że specyfikator dostępu dla nadrzędnej metody może zezwalać na więcej, ale nie mniej dostępu niż metoda nadpisana? Na przykład, metoda wystąpienia chronionego w klasie nadrzędnej może być upubliczniona, ale nie prywatna, w podklasie.

Author: BIBD, 2011-07-28

7 answers

Jest to podstawowa zasada w OOP: Klasa potomna jest pełnoprawną instancją klasy rodzicielskiej i dlatego musi prezentować co najmniej ten sam interfejs Co Klasa rodzicielska. Uczynienie rzeczy chronionych/publicznych mniej widocznymi naruszałoby ten pomysł; możesz sprawić, że klasy potomne staną się bezużyteczne jako instancje klasy nadrzędnej.

 53
Author: Patrick87,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 21:49:01

Wyobraź sobie te dwie klasy:

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

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

Mógłbym napisać ten kod:

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

I musiałaby być ważna, ponieważ na Animal metoda getName () jest publiczna, nawet jeśli została uczyniona prywatną na Lion. Nie jest więc możliwe, aby rzeczy były mniej widoczne na podklasach, ponieważ gdy będziesz mieć odniesienie do superklasy, będziesz mógł uzyskać dostęp do tych rzeczy.

 29
Author: Maurício Linhares,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 23:22:56

Bo to by było dziwne:

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!
 7
Author: Oliver Charlesworth,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 21:47:14

Weźmy przykład podany poniżej

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

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

Typowe nadpisywanie występuje w następującym przypadku

Person p=new Employee();

Tutaj {[2] } znajduje się odniesienie do obiektu z typem Person (SUPER class), gdy wywołujemy P.display () . Ponieważ modyfikator dostępu jest bardziej restrykcyjny, odniesienie do obiektu p nie można uzyskać dostępu do obiektu potomnego typu Employee

 7
Author: Vineeth Bhaskaran,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-07-05 06:20:52

Spóźniony na imprezę, ale chciałbym dodać jeszcze jedną troskę związaną z nadpisywaniem: metoda nadpisująca musi zezwalać na mniej (lub ten sam poziom) WYJĄTKÓW do wyrzucenia niż metoda nadpisywana; nawet nic nie da się wyrzucić.

Zasada substytucji Liskowa też może to wyjaśnić:

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
}

Powyżej metoda overridden zobowiązała się, że w najgorszym przypadku rzuci zwichnięcie, nie więcej (lekarz jest wymagany w miejscu kręcenia). Więc nadrzędne metoda nie może tego złamać, dodając więcej DeathException (lub karetka jest koniecznością)

Często nazywam nadrzędną regułą "[może być] więcej dostępu [poziom], [ale] mniej WYJĄTKÓW "

 3
Author: U and me,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-04-30 20:18:16

Ponieważ podklasa jest specjalizacją superklasy, lub innymi słowy, jest rozszerzeniem superklasy.

Wyobraź sobie na przykład metodę toString. Wszystkie obiekty Java mają to, ponieważ obiekt klasy ma to. Wyobraź sobie, że możesz zdefiniować klasę za pomocą metody ToString private. Wtedy nie traktujesz już wszystkich obiektów jednakowo. Na przykład, nie będzie już w stanie to bezpiecznie:

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

 0
Author: João Fernandes,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 21:48:34

Cóż, jeśli chodzi o konkretny przypadek, o którym wspomniałeś, jak dokładnie Java sobie z tym poradzi? Jeśli podklasa uczyniła metodę publiczną / chronioną prywatną, to co powinien zrobić JVM, gdy ta metoda jest wywoływana na instancji podklasy? Szanować szeregowca i powoływać się na implementację superklasy? Co więcej, łamiesz umowę określoną przez superklasę, gdy nagle mówisz: "nikt nie może uzyskać dostępu do tej metody, pomimo tego, co pierwotnie powiedział kontrakt."

 0
Author: Marvo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-27 21:49:05