2014-02-21 2 views
0

У меня есть защищенный метод (я не хочу, чтобы этот метод можно было увидеть вне суперкласса или его подклассов). Я хочу использовать его в конструкторе копирования, но не могу. Код:Использование Java защищенного метода суперкласса в конструкторе копии подкласса

public class Superclass { 
    protected HashMap<Object, Object> getData() { 
     return new HashMap<>(); 
    } 
} 

public class Subclass extends Superclass { 
    public Subclass(Superclass abstractClass) { 
     init(abstractClass); 
    } 

    private void init(Superclass abstractClass) { 
     //ERROR!!! getData has protected access in Superclass 
     for (Map.Entry<Object, Object> entry : abstractClass.getData().entrySet()) { 
      //do something 
     } 
    } 
} 

Как я могу решить эту проблему, если я все еще хочу, чтобы создать Подкласс объект из объекта Superclass, не подвергая метод GetData()?

EDIT Занятия в разных упаковках!

+0

Я получаю кучу других ошибок с этим кодом, но не тот, который вы упомянули –

+0

Извините, я написал этот код, чтобы он был похож на мой настоящий код проекта, но на самом деле не скомпилировал его. Я отредактирую его, чтобы он мог быть компилируемым. – DeGriz

+1

@DeGiz и, я подозреваю, что два класса находятся в разных пакетах, верно? Это будет важная информация! –

ответ

1

Хотя в том же пакете следующие прекрасно работает для меня:

Superclass:

public class Superclass { 
    protected List<String> getData() { 
     return Arrays.asList("a", "b", "c"); 
    } 
} 

Подкласс:

public class Subclass extends Superclass { 

public static void main(String[] args) { 
    Superclass superObject = new Superclass(); 
    Subclass subObject = new Subclass(superObject); 
} 

    public Subclass(Superclass abstractClass) { 
     //ERROR!!! getData has protected access in Superclass 
     for (String entry : abstractClass.getData()) { 
      System.out.println(entry); 
     } 
    } 
} 

заметь, я не уверен, что это то, что вы на самом деле пытаетесь сделать. Почему вы, например, передаете экземпляр Superclass в конструктор Subclass? Кроме того, у вас был HashMap, а не List, но HashMaps - это не Iterable, поэтому вы не можете использовать расширенный цикл для них.

Однако: Если эти классы находятся в разных пакетах, все меняется. Изучите спецификации языка; в §6.6.1 он говорит:

[I] е члена или конструктор объявляется защищен, то доступ разрешен только тогда, когда один из следующих условий:

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

  • Доступ действителен, как описано в п. 6..6.2.

И §6.6.2 состояния:

Защищенный член или конструктор объекта может быть доступен из вне пакета, в котором он объявлен только с помощью кода, который отвечает за реализацию, что объект.

Теперь, как вызов функции в методе инициализации является не считается ответственным за реализацию, вы не можете получить доступ к элементу здесь. Извините, так работает язык.

+0

Отредактированный код для его работы. – DeGriz

+1

Обратите внимание, что OP использует разные пакеты - когда два класса находятся в одном пакете, он работает, но 'protected' отказывает в доступе из других пакетов –

+0

Спасибо, я отредактировал свой ответ соответственно – blalasaadri

3

Вы пытались получить доступ к методу перед созданием экземпляра. Экземпляр еще не полностью инициализирован.

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

+0

Где это делается? –

+0

'bstractClass.getData()' в подклассе Constructor –

+2

Но 'abstractClass' является параметром, откуда вы знаете, что он еще не был полностью инициализирован? Он не ссылается на это! –

1

Доступ к защищенному методу из класса в другой упаковке невозможен - см. http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html. Тот факт, что вы наследуете от Superclass, не учитывается, поскольку вы пытаетесь вызвать метод по ссылке на Superclass, не на базовый класс.

Итак, что вы пытаетесь сделать, это не сработает - если бы это было так, это нарушило бы контроль доступа Java: вы могли бы просто наследовать от любого класса и реализовать метод, который принимает ссылку суперкласса в качестве параметра, а затем доступ ко всем защищенным методам суперкласса (вы можете, конечно же, унаследовать от базового класса и получить доступ к защищенным членам суперкласса, даже кросс-пакет).

Если getData() - это метод, который необходимо вызывать из другого пакета, вам необходимо сделать его общедоступным.

На боковой ноте вы должны, вероятно, переосмыслить свой дизайн - действительно ли необходимо передать ссылку на объект Superclass в конструкторе Subclass?

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