доступ к защищенному члену в java, вызвав его из объекта [duplicate]

«Slicing» - это то, где вы назначаете объект производного класса экземпляру базового класса, тем самым теряя часть информации - часть его «нарезана».

Например,

class A {
   int foo;
};

class B : public A {
   int bar;
};

Итак, объект типа B имеет два элемента данных: foo и bar.

Тогда, если вы должны были написать это:

B b;

A a = b;

Затем информация в b о члене bar теряется в a.

30
задан mahela007 2 September 2013 в 13:13
поделиться

6 ответов

Что здесь происходит?

Вы неправильно поняли значение protected. Вы можете получить доступ к защищенным членам, объявленным в A, из C, но только для экземпляров C или подклассов C. Подробнее о защищенном доступе см. В разделе 6.6.2 раздела JLS . В частности:

Пусть C - класс, в котором объявлен защищенный член. Доступ разрешен только внутри тела подкласса S из C.

Кроме того, если Id обозначает поле экземпляра или метод экземпляра, то:

  • [... ]
  • Если доступ осуществляется с помощью выражения доступа к полю E.Id, где E является первичным выражением или выражением вызова метода E.Id (...), где E является первичным выражением, то доступ разрешен тогда и только тогда, когда тип E является S или подклассом S.

(Emphasis mine.)

Итак этот код был бы точным:

C c = new C();
System.out.println(c.publicInt);
System.out.println(c.protectedInt);
35
ответ дан Jon Skeet 21 August 2018 в 08:23
поделиться
  • 1
    В этом случае, почему у java есть защищенный модификатор? Разве просто не было бы сделать C расширение A достаточным, чтобы сделать protectedInt видимым для C? – mahela007 2 September 2013 в 14:31
  • 2
    @ mahela007: Не без него protected, нет - если бы это была видимость по умолчанию (пакет) или private, это было бы не видно. – Jon Skeet 2 September 2013 в 14:34
  • 3
    Хм ... Подчеркнутая часть вашего ответа гласит: «доступ разрешен, если E является подклассом, если S». Но в моем примере C является подклассом A .. и я до сих пор не могу получить доступ к защищенной переменной. – mahela007 2 September 2013 в 17:24
  • 4
    @ mahela007: Но E здесь A, а S - C. Хотя C является подклассом A, A не является подклассом C. – Jon Skeet 2 September 2013 в 17:49
  • 5
    Также обратите внимание, что защищенные методы и переменные видны не только для дочерних классов, но и для классов внутри одного и того же пакета (как и объекты по умолчанию). Поэтому документация неверна, говоря & quot; тогда и только тогда, когда & quot; . (Попробуйте сами все). – Alex Semeniuk 9 June 2015 в 06:51
 public void go(){
        //remember the import statement
        A a = new A();
        System.out.println(a.publicInt);
        System.out.println(a.protectedInt);

    }

Когда вы делаете A a = new A(); и a.protectedInt, вы пытаетесь получить доступ к защищенному члену A, который является незаконным в соответствии со стандартами java

. Вместо этого вы можете делать this.protectedInt напрямую.

2
ответ дан Abhishek Singh 21 August 2018 в 08:23
поделиться

Защищенные средства:

a) Этот член будет доступен для всех классов в одном пакете с помощью ссылки объекта.

b) Для другого пакета это будет доступно только внутри Подклассы A говорят B и используемая ссылка могут быть экземплярами B или любого подкласса B.

Возьмем пример:

Пусть A - родительский класс в некотором пакете, скажем com.ex1 Пусть B, C - классы в разных пакетах по A say com.ex2. Кроме того, B extends A и C extends B. Мы увидим, как мы можем использовать защищенное поле A внутри B (подкласс A)

Код A:

public class A {
    protected int a = 10;
}

Код B:

public class B extends A {


    public void printUsingInheritance() {
        // Using this
        System.out.println(this.a);
    }


    public void printUsingInstantiation() {
        // Using instance of B
        B b = new B();
        System.out.println(b.a);

        // Using instance of C as C is subclass of B
        C c = new C();
        System.out.println(c.a);


        A a = new A();
        System.out.println(a.a); // Compilation error as A is not subclass of B
    }
}

Код C:

public class C extends B {

}

Для защищенных статических:

Те же правила применяются, за исключением того, что в b) теперь он доступен в любом подклассе класса A по ссылке класса A. [Д0] Ссылка

0
ответ дан Breaking Benjamin 21 August 2018 в 08:23
поделиться

В том же пакете, где объявлен защищенный член, разрешен доступ:

package package1;

public class C extends A{
    public void go(){
        A a = new A();
        System.out.println(a.protectedInt);  // got printed 
        C c = new C();
        System.out.println(c.protectedInt);  // got printed as well
    }
}

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

package package2;

public class C extends A{
    public void go(){
        A a = new A();
        System.out.println(a.protectedInt);  // compiler complains  
        C c = new C();
        System.out.println(c.protectedInt);  // got printed
    }
} 
1
ответ дан Ethan 21 August 2018 в 08:23
поделиться

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

public class C extends A{

    public void go(){

       System.out.println(protectedInt);

    }
}

. В соответствии с вашим кодом вы создаете экземпляр из A и доступа к protected переменной через этот экземпляр , который нарушает правило java. Защищенная переменная не видна вне пакета

10
ответ дан sanbhat 21 August 2018 в 08:23
поделиться
  • 1
    Исходный код будет работать, если оба класса находятся в одном пакете. – blgt 2 September 2013 в 13:40
  • 2
    Я прочитал это из документа JLC, который опубликовал Jon skeet. «Защищенный член или конструктор объекта может быть доступен извне пакета, в котором он объявляется только кодом, который отвечает за реализацию этого объекта». Как может код, который «реализует объект», быть вне пакета одного и того же объекта? – mahela007 2 September 2013 в 17:14
  • 3
    @ mahela007: Посмотрите на свой пример - члены объявлены в A, который находится в другом пакете с классом C, который является тем, что «реализует». объект типа C. – Jon Skeet 2 September 2013 в 19:11
1
ответ дан Sugumar 21 August 2018 в 08:23
поделиться
Другие вопросы по тегам:

Похожие вопросы: