2013-02-18 1 views
1

я явно не хватает очевидного в этом, но учитывая:java protected Почему это работает через ненаследование?

package a; 
public class Class1 { 
    protected int a=1; 
} 

package b; 
import a.*; 

public class Class2 extends Class1 { 
    Class2() { 
     Class1 c1=new Class1(); 
     Class2 c2=new Class2(); 
     System.out.println(a);  //1 
     System.out.println(c1.a); //2 
     System.out.println(c2.a); //3 
    } 
} 

Я знаю // 1 отлично, так как используется в порядке наследования и // 2 терпит неудачу, потому что он не является доступ через наследование, но почему // 3 тоже нормально? Я думал, что переменная a была доступна через новый объект и находится в Class1?

Спасибо.

+0

не имеет отношения к актуальному вопросу, но вызов этого конструктора вызовет 'StackOverflowError'. – jlordo

+0

Да, спасибо. Я положил его в основное, но потом взял его, чтобы сэкономить на количестве строк кода и позволить мне вставить строку // 1 :) –

ответ

4

Когда вы манипулируете объектом внутри своего класса, у вас есть полный доступ ко всем его атрибутам, в том числе к частным. Поскольку c2 является экземпляром Class2, и вы управляете им внутри кода Class2, вы можете увидеть защищенный атрибут.

+0

Спасибо. Поэтому, если никакие данные, скрывающие Class2, не наследуют все Class1, поэтому «a» эффективно становится частью класса 2 в качестве защищенного элемента. –

+0

'включая частные .' -> Извините ?? –

+0

@RohitJain Если у вас есть класс под названием «Тест», и у вас есть атрибут, объявленный 'private int abc;' вы можете объявить переменную 'Test t = new Test();' и сделать что-то вроде 't.abc = 123; 'если вы находитесь в классе' Test' –

4

Так как любой объект Class2 является разновидностью Class1, он может получить доступ ко всем переменным членов Class 1 «ы с областями default, protected и public.

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

например, это разрешено:

public class Something { 
    private int something; 

    public int stealSomething(final Something otherthing) { 
     return otherthing.something; 
    } 
} 

Попробуйте сделать третий класс, который не находится в иерархии классов, которые вы используете для тестирования.

+0

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

1

Я не понимаю проблему.

Класс1 имеет переменную с именем 'a'. Поскольку он «защищен», эта переменная видна внутри любого объекта Class1 и любого объекта класса, расширяющего Class1.

Если 'a' были закрытыми, тогда это не было бы видимым таким образом в объектах классов, расширяющих Class1.

+0

не в подклассе в другом пакете –

+0

«Class2 extends Class1» - это подкласс, здесь нет никакого другого пакета. – arcy

3

Почему // 3 нормально?

И почему не должно быть в порядке? Учитывая, что Class2 является подклассом Class1, поэтому поля protectedClass1 доступны через экземпляр Class2. И вот что вы здесь делаете. c2 - это пример Class2, и поле a видно.

ПРИМЕЧАНИЕ:защищенный член доступен любой прямой подкласс, будь то в одном пакете или в другом пакете.

Я думал, что переменная а в настоящее время доступны через новый объект

Да, это правда.

и находится в Class1?

Это действительно не имеет значения. Поскольку a доступен для экземпляра Class2, он действителен.

И только FYI, ваш код будет умирать от StackOverflowError. Вы должны позаботиться об этом.

+0

Да, спасибо. Я поместил его в основное, но затем взял его, чтобы сохранить количество строк кода и позволить мне помещать строку // 1 :) это просто проверка кода, а не реальный бит кода –

+0

@Neil. ОК. Тогда все в порядке. –