2012-03-19 2 views
0

У меня есть следующий код:Почему более слабые переопределенные функции не разрешены в Java?

public class Library { 

    public void myFunction() { 
     // do something 
    } 
} 
public class Book extends Library{ 

    protected void myFunction() { // Error here 
     // do something 
    } 

} 

Приведенные выше код имеет ошибку, потому что класс Книги пытается переопределить функцию класса ужина с более слабым модификатором доступа. Я знаю, что это правило Java. Но мне любопытно, почему? Какая проблема может возникнуть?

ответ

5

Рассмотрим, из совершенно другой пакет:

new Book().myFunction()    // clearly, no access 

((Library)new Book()).myFunction() // now ... access? 

Вопрос действительно сводится к myFunction быть виртуальный; вызываемый метод зависит от runtime-type, а не от статического типа выражения. (Я считаю, что C# на самом деле допустил бы это для не виртуального метода с модификатором new.)

0

Конечно, потому что, если кому-то дана библиотека, тогда ему должно быть позволено позвонить myFunction, поскольку он является публичным в его подписи.

Итак, если вы вернете книгу, например Library test = getALibraryObject();, вы увидите, что метод не может быть защищен в каком-либо объекте, а не в других.

0

Ваш пример немного с тех пор, как книга не является библиотекой. Но давайте рассмотрим автомобиль и грузовик.

public class Car { 
    public start() {} 
} 

public class Truck extends Car { 
    protected start() {} 
} 

Car c = new Truck(); // should be possible yes? 
c.start(); // this is why you cannot change access modifiers in sub classes 
0

Допустим, что есть класс Reader

public class Reader { 
    private final Library library; 

    public Reader(Library library) { 
    this.library = library; 
    } 

    public void read() { 
    library.read(); 
    } 
} 

, который инициализируется с экземпляром Book:

Reader reader = new Reader(new Book()); 

Тогда читатель не сможет прочитать так как его метод read не отображается в контексте Reader. Reader может получить способ Libraryread, но не может получить Bookread метод, что довольно странно, да?

-1

это правило объектно-ориентированного языка. Вы не можете связать контроль доступа с помощью метода overriden. , если переопределенный метод защищен, тогда вы можете переопределить его как общедоступный, но наоборот невозможно.

+0

Это не правило «Объектно-ориентированный язык». Это не имеет никакого отношения к OO. Элементарным принципом является то, что первоначально указанная безопасность не должна быть обратимой. – EJP

+0

что отличает принцип и правило? –

+0

Как сказал EJP, он не имеет ничего общего с объектной ориентацией. Кроме того, как говорит pst, в C# можно сделать что-то подобное, используя «новое» ключевое слово. И C# также объектно-ориентирован. – Christian

Смежные вопросы