Protected Data in Parent Class Not Available in Child Class

Protected data in parent class not available in child class?

According to TC++PL, pg 404:

A derived class can access a base class’ protected members only for objects of its own type.... This prevents subtle errors that would otherwise occur when one derived class corrupts data belonging to other derived classes.

Of course, here's an easy way to fix this for your case:

class A
{
protected:
int data;
};

class B : public A
{
public:
B(const A &a)
: A(a)
{
}
};

int main()
{
A a;
B b = a;
return 0;
}

Protected variable not accessible within child class in Java

That happens because you confusing static and instance members.

AnimalApp.animalName - is a way to refer to a static variable (by using the class name, because static variable resides on the class, they do not belong to any instance of the class and hence cant be inherited).

this.animalName or super.animalName or simply animalName - are proper ways to access instance variables

Parent's protected properties inaccessible to child object

They are accessible, but they will be null because they are not passed to the parent constructor from the child:

(new ChildClass(1,2))->anotherFakeMethod();

Sandbox

Output

NULL

Your classes produce the expected result of null in this case. Well it produces what I would expect it to based on how it's coded.

To fix it, you must pass that data back to the parent class through the child's constructor, or remove the child's constructor. Like this:

class ChildClass extends ParentClass {

public function __construct($prop1, $prop2) {
parent::__construct($prop1, $prop2);
}
....
}

After the above change:

(new ChildClass(1,2))->anotherFakeMethod();

Output

int(1)

Sandbox

Which is what I would expect from this line as it's basically the first argument used in the constructor:

var_dump($this->prop1);

You can also do it this way, if you know what they are in the child class:

public function __construct() {
parent::__construct(1, 2); //say I know what these are for this child
}

You could of course set them manually in the new constructor but that would be WET (write everything twice) or unnecessary duplication, in this case.

Cheers!

Prevent Child class from accessing protected member variable of Grandparent class

MatG's comment about searching "c++ inheritance change member access specifier" answered by question. I didn't realize you could change the access modifier of a parent class member in a derived class.

class Parent : Grandparent
{
protected:
void setObj(val) { m_obj = val; }
MyClass getObj { return val; }
private:
using Grandparent::m_obj;
}

Protected variables can be accessed within Child Class or Child Object

Disclaimer: the answer is copied from my answer of another question. However no answer from that question is accepted. I believe it also suit this question therefore I am copying the content with some minor editing to here.

protected is a bit interesting in Java. Although we always says "protected" give access to subclass of different package, it is not the whole picture.

For example, if you have Child extending Parent, and there is a protected member in Parent. What you can do in Child is to access that protected member of Child, but not even that protected member of Parent. Sounds a bit strange right although they sounds the same thing?

Quoted from Core Java 9th Edition:

However, the Manager class methods can peek inside the hireDay field
of Manager objects only, not of other Employee objects. This
restriction is made so that you can’t abuse the protected mechanism by
forming subclasses just to gain access to the protected fields

(class Manager extends Employee, and there is a hireDay protected member in Employee, and Manager and Employee are located in DIFFERENT package)

For example,

public class Manager extends Employee {
// accessing protected member of itself
public void foo1() {
System.out.println("" + this.hireDay); // OK
}

// access protected member of instance of same type
public void foo2(Manager manager) {
System.out.println("" + manager.hireDay); // OK
}

// access protected member of instance of super-class
public void foo3(Employee employee) {
System.out.println("" + employee.hireDay); // NOT ALLOWED!
}
}

Which means, protected member allow child class from another package to access through reference of that child class (either this, or another reference that is-a child class)

And, be specific to OP's answer: if callMethod is declared in ChildClass, then NO, you cannot do it and it will not even compile. However if callMethod is declared in ParentClass then everything is fine, because it is simply ParentClass accessing protected member of a ParentClass instance.


Update:

Given criticisms in comment, I think it worth to go to JLS to see what it say:

(Quoted from http://docs.oracle.com/javase/specs/jls/se8/html/jls-6.html#jls-6.6.2.1 about Access to a protected Member, second bullet)

If the access is by a field access expression E.Id, or a method
invocation expression E.Id(...), or a method reference expression E ::
Id, where E is a Primary expression (§15.8), then the access is
permitted if and only if the type of E is S or a subclass of S

This is essentially what I was trying to deliver in the answer:

Within Manager class, manager.hireDay works because manager is a primary expression, and the access is permitted because type of manager is Manager or subclass of Manager.

So, based on JLS, why manager.hireDay works DOES have relationship with type of manager (being the same type).

Java - Why Child in another package cannot access parent's protected method through parent reference?

The error you're seeing makes total sense.

When you do the following

ParentClass par = new ParentClass();
par.testProtected();

you're trying to access testProtected as if it were part of the public API of ParentClass, that's it, you're calling from another package a protected method of ParentClass on an instance of that class. It doesn't matter it is being called inside an extending class, all that matters is that it's being called from another package.

Now, if you do

ChildClass ch = new ChildClass();
ch.testProtected(); // Line 3
testProtected(); // Line 4

you will not see any errors. Why?

In line 3 you're accessing a method upon an instance of class ChildClass inside ChildClass, so that's legal. Even if you would have had a private method childMethod in ChildClass you could have done ch.childMethod().

In line 4 you're accessing testProtected through the this reference (implicitly), it means it calls the method through the ChildClass, which, again is legal.

See this related post: What is the difference between public, protected, package-private and private in Java? (hint: last row in the described table)

C++ Protected Variables Not Inherited

The error has nothing to do with the access level of the members of class rsa. Even if you declare those members public you will still get the error. The problem is that a derived class's initialization list is run solely in the context of itself, you do not have access to base class members.

You can however access base class members (that are public or protected) in the body of a derived class constructor. Ex:

class public_key : public rsa
{
public:
public_key()
{
n = 0;
e = 0;
c = 0;
k = 0;
end = 0;
f = 0;
}
};

class private_key : public rsa
{
public:
private_key()
{
n = 0;
e = 0;
c = 0;
k = 0;
end = 0;
f = 0;
}
};

Though the above code uses assignment instead of initialization, it does the exact same thing under the hood for primitive types, which all of those members are.

Still, though the above code works, it is the wrong way of doing what you want. You have already written a constructor for class rsa, so one way to avoid duplicating code is to call your existing constructor from the initialization list.

class public_key : public rsa
{
public:
public_key() : rsa()
{ }
};

class private_key : public rsa
{
public:
private_key() : rsa()
{ }
};

However note that rsa() is the default constructor (since it has no parameters) so it will automatically be called by any constructor of the derived class (unless you specify some other rsa constructor in the initialization list).

class public_key : public rsa
{
public:
public_key()
{ } // rsa() will be called automatically
};

class private_key : public rsa
{
public:
private_key()
{ } // rsa() will be called automatically
};

But now that your derived class's have empty default constructors, you do not even need them (unless you plan to add more logic).

class public_key : public rsa
{
public:
// rsa() will still be called automatically when declaring an instance of public_key
};

class private_key : public rsa
{
public:
// rsa() will still be called automatically when declaring an instance of private_key
};

As to your side note on the key() function, if the implementation of key() was the same in both child classes then yes, you only need it once in the parent class. You should always avoid code duplication so even if a small part of key() needed to be customized for each child class, you are better off writing a virtual function in the base class that key() can call as part of the calculation. Then, in each child class, override the virtual function with whatever specialization is necessary. Thus all the shared code can remain in the parent class key() function.



Related Topics



Leave a reply



Submit