2013-12-05 3 views
4

Я просмотрел так много веб-сайтов, которые объясняют спецификаторы доступа в java, такие как java papers, java's access specifiers и многие другие вопросы, связанные с stackoverflow, такие как here.Доступ к защищенной переменной из подкласса снаружи пакета

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

При экспериментировании с защищенными членами я узнал, что я не могу получить доступ к защищенному члену из внешнего класса подкласса.

Проверьте, пожалуйста, код. Общий класс с защищенными членами:

package com.One; 

    public class ProVars { 

    protected int i = 900; 

    protected void foo() 
    { 
     System.out.println("foo"); 
    } 

} 

Другой общественный класс в другом пакете пытается получить доступ к защищенному члену:

package com.Two; 

import com.One.ProVars; 

public class AnotherClass extends ProVars { 

    public static void main(String[] args) { 
     ProVars p = new ProVars(); 
     System.out.println(p.i);//the field ProVars.i is not visible(Compilation Error) 
       p.foo();//the method foo() from the type ProVars is not visible 

    } 
} 

Любое объяснение ценится.

ответ

8

Вы пытаетесь использовать их, как если бы они были public. Они не public, они protected.

Пример

ProVars p = new ProVars(); 
p.foo(); // This will throw an error because foo() is not public. 

правильное использование, для подкласса использовать метод или переменную protected является:

public class MyClass extends ProVars 
{ 
    public MyClass() 
    { 
      System.out.println(i); // I can access it like this. 
      foo(); // And this. 
    } 
} 

Почему это работает?

Потому что у вас есть inherited класс. Это означает, что у вас есть все его методы и переменные. Теперь, поскольку ваш метод и переменная protected, это также означает, что к нему можно получить доступ с subclass. Попробуйте и объявите их как private и посмотрите, что произойдет.

+1

Спасибо за четкое объяснение. Таким образом, мы могли получить доступ к защищенным членам в подклассе, но не можем получить к ним доступ объектом super class. – chaitanya89

+0

Правильно! Рад, что ты там! – christopher

5

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

Внутри AnotherClass вы можете получить доступ к new AnotherClass().i, но не new ProVars().i.

+1

Спасибо за ответ. Ваш ответ правильный, но я принял ответ Криса, потому что он хорошо его разработал. Надеюсь, вы не против. – chaitanya89

0

Когда мы говорим, что это доступно из подкласса, мы имеем в виду, что он доступен для подкласса. Но в вашем примере вы вызываете защищенный метод извне.

Так, пока ваш пример не работает, это должно

package com.Two; 

import com.One.ProVars; 

public class AnotherClass extends ProVars { 

public static void main(String[] args) { 
    ProVars p = new ProVars(); 
    p.test(); 
} 

public test() { 
     System.out.println(this.i);) 
     this.foo(); 
} 



} 
1

Используйте подкласс В вашем main():

public class AnotherClass extends ProVars { 

    public static void main(String[] args) { 
    AnotherClass p = new AnotherClass(); 
    System.out.println(p.i); 
      p.foo(); 

} 

} 
0

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

Попробуйте перевести код в метод внутри класса NewClass и затем вызвать этот метод из вашего статического метода.

3

Было бы замечательно, если бы ваш основной метод не был статическим. Статические методы не заботятся о наследовании, поэтому ваш «расширяет ProVars» не будет работать. Это с другой стороны, должны работать:

public class AnotherClass extends ProVars { 

public void accessProtected() { 
    System.out.println(this.i); 
    this.foo(); 
} 

public static void main(String[] args) { 
    AnotherClass p = new AnotherClass(); 
    p.accessProtected(); 
} 

} 
1

Вам нужно изменить строку ProVars p = new ProVars(); в AnotherClass p = new AnotherClass();

В противном случае, вы по-прежнему создает объект ProVars типа, и вона компилятор» t реализовать наследование между AnotherClass и ProVars (что приводит к ошибке компиляции).

0

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

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

ProVars p = new ProVars(); System.out.println (p.i); // ошибка: я имею защищенный доступ в родительском

просто использовать это в вашем подклассе:

System.out.println (I); // отлично работает, поскольку подкласс наследует защищенного члена суперкласса, независимо от того, находятся ли они в одинаковом или другом пакете.

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