Почему не удается получить доступ к защищенному члену родительского класса? [Дубликат]

Все это хорошие ответы. Я хотел бы добавить пример выполнения при передаче объектов по значению vs по ссылке:

#include <iostream>

using namespace std;

// Base class
class A {
public:
    A() {}
    A(const A& a) {
        cout << "'A' copy constructor" << endl;
    }
    virtual void run() const { cout << "I am an 'A'" << endl; }
};

// Derived class
class B: public A {
public:
    B():A() {}
    B(const B& a):A(a) {
        cout << "'B' copy constructor" << endl;
    }
    virtual void run() const { cout << "I am a 'B'" << endl; }
};

void g(const A & a) {
    a.run();
}

void h(const A a) {
    a.run();
}

int main() {
    cout << "Call by reference" << endl;
    g(B());
    cout << endl << "Call by copy" << endl;
    h(B());
}

Выход:

Call by reference
I am a 'B'

Call by copy
'A' copy constructor
I am an '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 в 16:11
поделиться
  • 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 в 16:11
поделиться

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

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 в 16:11
поделиться

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

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 в 16:11
поделиться
10
ответ дан sanbhat 21 August 2018 в 16:11
поделиться

Не нужно создавать экземпляр класса защиты внутри класса Protection2. Вы можете напрямую вызвать защищенную переменную без создания экземпляра класса защиты. Поскольку класс Protection2 расширяет класс защиты. Таким образом, переменная автоматически унаследована подклассом.

Попробуйте использовать код ниже:

public class Protection2 extends Protection{
Protection2()
{System.out.println("n_pro = " +n_pro);
}}
1
ответ дан Sugumar 21 August 2018 в 16:11
поделиться
Другие вопросы по тегам:

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