Разница в доступности методов класса и методов интерфейса в Java - PullRequest
0 голосов
/ 14 апреля 2020

Почему класс ref и интерфейсный тип интерфейса имеют разные области доступа для своих методов.

В следующем примере

interface ImInterface{

   void do1();

   void do2();

}


class MyClass implements ImInterface {

   void do1(){
   System.out.println("do1");
   }

   void do2(){
    System.out.println("do2");
   }

   void do3(){
    System.out.println("do3");
   }
}

Не могли бы вы помочь мне понять, почему переменная mc определен как

MyClass mc = new MyClass();

не может получить доступ к do1 and d2 без приведения? Он реализует всю функциональность из контракта (ImInterface). Почему это так в Java?

Кроме того, почему mi, определенный как

MyInterface mi = new MyClass();

, не может получить доступ к do3 без какого-либо приведения?

Я знаю, что mi и mc имеют разные типы, но после того, как реализации теперь стали единым целым, тогда почему разница в доступе без приведения? mc и mi оба указывают на один и тот же тип экземпляра.

Ответы [ 3 ]

2 голосов
/ 14 апреля 2020

Поскольку вы объявляете объект mi как тип MyInterface, у вас будет доступ только к методам, которые объявлены в MyInterface.

Когда вы объявите объект mc как типа MyClass, у вас будет доступ ко всем методам, объявленным в MyClass и его суперклассе.

Когда Java смотрит на ссылку mi, он просто будет знать, что она имеет тип MyInterface.

Теперь, если вы объявили mc вне пакета, вы не сможете получить доступ ни к одному из их методов, поскольку они имеют видимость пакета.

1 голос
/ 14 апреля 2020

Методы интерфейса неявно publi c, а методы класса без указанного модификатора доступа имеют более слабые права доступа, чем publi c.

Когда вы реализуете метод интерфейса, реализующий класс не может иметь более слабый модификатор доступа к нему, чем указано в интерфейсе.

В вашем примере вы пытаетесь реализовать интерфейс с неявно опубликованными методами c через методы, у которых нет модификатора , что нарушает указанное выше правило. Если вы хотите, чтобы этот код работал, вы должны явно указать эти методы: publi c.

mi не может получить доступ к do3(), поскольку у него нет информации об этом методе в объявлении ImInterface (и * Тип 1020 * s ImInterface). По этой причине вам нужно явно привести mi к MyClass, сообщив Java, что он может обрабатывать этот объект более «узкими» способами.

Вы можете найти больше информации об интерфейсах здесь .

1 голос
/ 14 апреля 2020

Почему m c не может получить доступ к do1 и d2 без приведения?

Может, при условии, что вы вызываете mc.do1() или mc.do2() из класса в том же пакете, где MyClass объявлен. В Java, когда вы не объявляете модификатор доступа для метода или поля, Java позволяет ему быть доступным только в том же «пакете», где объявлен класс. Чтобы do1 () и do2 () были доступны где угодно, объявите их с помощью publi c 'modifier':

public void do1() {
   ...
}

Примечание. Это не применимо для интерфейсов, так как все методы в интерфейсах по умолчанию 'publi c', даже если ключевое слово не указано.

Почему mi не может получить доступ к do3 без приведения?

Вот как устроен Java. Интерфейс определяет контракт ( что , а не как ). Поэтому, когда класс реализует интерфейс, он должен придерживаться этого контракта, плюс он может объявлять свои собственные функции. Но пока вы ссылаетесь на объект класса реализации со ссылкой на интерфейс:

MyInterface mi = new MyClass();

ссылка на интерфейс будет иметь доступ только к объявленному методу. Другими словами, ссылка на интерфейс может сказать только то, что она «знает наверняка», присутствует в реализации (так как класс реализации реализовал интерфейс), а не другие функциональные возможности (методы) класса реализации.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...