Вызов метода private-пакета из main после вызова конструктора - PullRequest
1 голос
/ 16 ноября 2011

Я изучаю SCJP, и во время обучения я нашел упражнение, которое на первый взгляд казалось очень простым, но мне не удалось его решить, и я не понимаю ответа. В упражнении (взятом из практических экзаменов для программистов OCP Java SE 6 , Берт Бейтс и Кэти Сьерра) говорится следующее:

Дано:

import java.util.*;
public class MyPancake implements Pancake {
  public static void main(String[] args) {
    List<String> x = new ArrayList<String>();
    x.add("3");x.add("7");x.add("5");
    List<String> y = new MyPancake().doStuff(x);
    y.add("1");
    System.out.println(x);
  }

  List<String> doStuff(List<String> z) {
    z.add("9");
    return z;
  }
}

interface Pancake {
  List<String> doStuff(List<String> s);
}


What is the most likely result?

A. [3, 7, 5]

B. [3, 7, 5, 9]

C. [3, 7, 5, 9, 1]

D. Compilation fails.

E. An exception is thrown at runtime

И ответ:

D is correct. MyPancake.doStuff() must be marked public. If it is, then C would be
correct.

A, B, C, and E are incorrect based on the above.

Я предположил, что C, потому что метод doStuff находится внутри класса MyPancake, поэтому основной метод должен иметь к нему доступ.

Если пересмотреть вопрос, при вызове new из статического контекста он может не иметь доступа к закрытым методам, если doStuff был закрытым. Это правда? Я не уверен в этом.

Но в любом случае, я все еще думаю, что у него будет доступ к приватному методу пакета doStuff. Наверное, я не прав, но не знаю почему.

Не могли бы вы мне помочь?

Спасибо!

Ответы [ 3 ]

4 голосов
/ 16 ноября 2011

Очень грустно, что он не дает вам ответа относительно , почему он не сможет скомпилироваться - но, к счастью, когда у вас есть компилятор, вы можете узнать сами:

Test.java:11: error: doStuff(List<String>) in MyPancake cannot implement doStuff
(List<String>) in Pancake
  List<String> doStuff(List<String> z) {
               ^
  attempting to assign weaker access privileges; was public
2 errors

В основном члены интерфейса всегда являются открытыми, поэтому вам необходимо реализовать интерфейсы с помощью открытых методов.Это не проблема вызова метода - это проблема реализации интерфейса.Если бы вы сняли часть «инвентарь», она бы работала нормально.

Из раздела 9.1.5 спецификации языка Java :

Все члены интерфейса являютсябезоговорочно публично.Они доступны вне пакета, в котором интерфейс объявлен, если интерфейс также объявлен открытым или защищенным, в соответствии с правилами §6.6.

2 голосов
/ 16 ноября 2011

Когда вы определяете метод

List<String> doStuff(List<String> s);

В интерфейсе Pancake вы действительно говорите:

public List<String> doStuff(List<String> s);

Поскольку все методы в интерфейсе всегда общедоступны, даже если вы не расшифруете, пометьте их как таковые.

Теперь класс MyPancake имеет доступ по умолчанию, назначенный методу doStuff (List s), и поэтому не следует интерфейсу, а код не компилируется.

2 голосов
/ 16 ноября 2011

Когда вы реализуете интерфейс Pancake.

Вы предоставляете реализацию метода doStuff () в вашем классе MyPancake

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

Следовательно, когда вы не предоставляете модификатор доступа, это уменьшает видимость.

...