Related
This is an interview question.
Does subclasses inherit private
fields?
I answered "No", because we can't access them using the "normal OOP way". But the interviewer thinks that they are inherited, because we can access such fields indirectly or using reflection and they still exist in the object.
After I came back, I found the following quote in the javadoc:
Private Members in a Superclass
A
subclass does not inherit the private
members of its parent class.
Do you know any arguments for the interviewer's opinion?
Most of the confusion in the question/answers here surrounds the definition of Inheritance.
Obviously, as #DigitalRoss explains an OBJECT of a subclass must contain its superclass's private fields. As he states, having no access to a private member doesn't mean its not there.
However. This is different than the notion of inheritance for a class. As is the case in the java world, where there is a question of semantics the arbiter is the Java Language Specification (currently 3rd edition).
As the JLS states (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):
Members of a class that are declared
private are not inherited by
subclasses of that class. Only members
of a class that are declared protected
or public are inherited by subclasses
declared in a package other than the
one in which the class is declared.
This addresses the exact question posed by the interviewer: "do subCLASSES inherit private fields". (emphasis added by me)
The answer is No. They do not. OBJECTS of subclasses contain private fields of their superclasses. The subclass itself has NO NOTION of private fields of its superclass.
Is it semantics of a pedantic nature? Yes. Is it a useful interview question? Probably not. But the JLS establishes the definition for the Java world, and it does so (in this case) unambiguously.
EDITED (removed a parallel quote from Bjarne Stroustrup which due to the differences between java and c++ probably only add to the confusion. I'll let my answer rest on the JLS :)
Yes
It's important to realize that while there are two classes, there is only one object.
So, yes, of course it inherited the private fields. They are, presumably, essential for proper object functionality, and while an object of the parent class is not an object of the derived class, an instance of the derived class is mostly definitely an instance of the parent class. It could't very well be that without all of the fields.
No, you can't directly access them. Yes, they are inherited. They have to be.
It's a good question!
Update:
Err, "No"
Well, I guess we all learned something. Since the JLS originated the exact "not inherited" wording, it is correct to answer "no". Since the subclass can't access or modify the private fields, then, in other words, they are not inherited. But there really is just one object, it really does contain the private fields, and so if someone takes the JLS and tutorial wording the wrong way, it will be quite difficult to understand OOP, Java objects, and what is really happening.
Update to update:
The controversy here involves a fundamental ambiguity: what exactly is being discussed? The object? Or are we talking in some sense about the class itself? A lot of latitude is allowed when describing the class as opposed to the object. So the subclass does not inherit private fields, but an object that is an instance of the subclass certainly does contain the private fields.
No. Private fields are not inherited... and that's why Protected was invented. It is by design. I guess this justified the existence of protected modifier.
Now coming to the contexts. What you mean by inherited -- if it is there in the object created from derived class? yes, it is.
If you mean can it be useful to derived class. Well, no.
Now, when you come to functional programming the private field of super class is not inherited in a meaningful way for the subclass. For the subclass, a private field of super class is same as a private field of any other class.
Functionally, it's not inherited. But ideally, it is.
OK, just looked into Java tutorial they quote this:
Private Members in a Superclass
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
refer: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
I agree, that the field is there. But, subclass does not get any privilege on that private field. To a subclass, the private field is same as any private field of any other class.
I believe it's purely matter of point-of-view. You may mould the argument either side. It's better justify both way.
It depends on your definition of "inherit". Does the subclass still have the fields in memory? Definitely. Can it access them directly? No. It's just subtleties of the definition; the point is to understand what's really happening.
I will demonstrate the concept with code. Subclasses ACTUALLY inherit the private variables of super class. The only problem is that they are not accessible to the
child objects unless you provide public getters and setters for the private variables
in the super class.
Consider two class in package Dump. Child extends Parent.
If I remember correctly, a child object in memory consists of two regions. One is the parent part only and the other is the child part only. A child can access the private
section in the code of its parent only via a public method in the parent.
Think of it this way. Borat's father Boltok has a safe containing $100,000. He does not want to share his "private" variable safe. So, he does not provide a key for the safe. Borat inherits the safe. But, what good is it if he cannot even open it ? If only his
dad had provided the key.
Parent -
package Dump;
public class Parent {
private String reallyHidden;
private String notReallyHidden;
public String getNotReallyHidden() {
return notReallyHidden;
}
public void setNotReallyHidden(String notReallyHidden) {
this.notReallyHidden = notReallyHidden;
}
}//Parent
Child -
package Dump;
public class Child extends Parent {
private String childOnly;
public String getChildOnly() {
return childOnly;
}
public void setChildOnly(String childOnly) {
this.childOnly = childOnly;
}
public static void main(String [] args){
System.out.println("Testing...");
Child c1 = new Child();
c1.setChildOnly("childOnly");
c1.setNotReallyHidden("notReallyHidden");
//Attempting to access parent's reallyHidden
c1.reallyHidden;//Does not even compile
}//main
}//Child
No. They don't inherit it.
The fact some other class may use it indirectly says nothing about inheritance, but about encapsulation.
For instance:
class Some {
private int count;
public void increment() {
count++;
}
public String toString() {
return Integer.toString( count );
}
}
class UseIt {
void useIt() {
Some s = new Some();
s.increment();
s.increment();
s.increment();
int v = Integer.parseInt( s.toString() );
// hey, can you say you inherit it?
}
}
You can also get the value of count inside UseIt via reflection. It doesn't means, you inherit it.
UPDATE
Even though the value is there, it is not inherited by the subclass.
For instance a subclass defined as:
class SomeOther extends Some {
private int count = 1000;
#Override
public void increment() {
super.increment();
count *= 10000;
}
}
class UseIt {
public static void main( String ... args ) {
s = new SomeOther();
s.increment();
s.increment();
s.increment();
v = Integer.parseInt( s.toString() );
// what is the value of v?
}
}
This is exactly the same situation as the first example. The attribute count is hidden and not inherited by the subclass at all. Still, as DigitalRoss points out, the value is there, but not by means on inheritance.
Put it this way. If your father is wealthy and gives you a credit card, you can still buy thing with his money, but doesn't mean you have inherited all that money, does it?
Other update
It is very interesting though, to know why the attribute is there.
I frankly don't have the exact term to describe it, but it's the JVM and the way it works that loads also the "not inherited" parent definition.
We could actually change the parent and the subclass will still work.
For instance:
//A.java
class A {
private int i;
public String toString() { return ""+ i; }
}
// B.java
class B extends A {}
// Main.java
class Main {
public static void main( String [] args ) {
System.out.println( new B().toString() );
}
}
// Compile all the files
javac A.java B.java Main.java
// Run Main
java Main
// Outout is 0 as expected as B is using the A 'toString' definition
0
// Change A.java
class A {
public String toString() {
return "Nothing here";
}
}
// Recompile ONLY A.java
javac A.java
java Main
// B wasn't modified and yet it shows a different behaviour, this is not due to
// inheritance but the way Java loads the class
Output: Nothing here
I guess the exact term could be found here: The JavaTM Virtual Machine Specification
Well, my answer to interviewer's question is - Private members are not inherited in sub-classes but they are accessible to subclass or subclass's object only via public getter or setter methods or any such appropriate methods of original class. The normal practice is to keep the members private and access them using getter and setter methods which are public. So whats the point in only inheriting getter and setter methods when the private member they deal with are not available to the object? Here 'inherited' simply means it is available directly in the sub-class to play around by newly introduced methods in sub-class.
Save the below file as ParentClass.java and try it yourself ->
public class ParentClass {
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
class SubClass extends ParentClass {
private int y;
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void setXofParent(int x) {
setX(x);
}
}
class Main {
public static void main(String[] args) {
SubClass s = new SubClass();
s.setX(10);
s.setY(12);
System.out.println("X is :"+s.getX());
System.out.println("Y is :"+s.getY());
s.setXofParent(13);
System.out.println("Now X is :"+s.getX());
}
}
Output:
X is :10
Y is :12
Now X is :13
If we try to use private variable x of ParentClass in SubClass's method then it is not directly accessible for any modifications (means not inherited). But x can be modified in SubClass via setX() method of original class as done in setXofParent() method OR it can be modified using ChildClass object using setX() method or setXofParent() method which ultimately calls setX(). So here setX() and getX() are kind of gates to the private member x of a ParentClass.
Another simple example is Clock superclass has hours and mins as private members and appropriate getter and setter methods as public. Then comes DigitalClock as a sub-class of Clock. Here if the DigitalClock's object doesn't contain hours and mins members then things are screwed up.
Ok, this is a very interesting problem I researched a lot and came to a conclusion that private members of a superclass are indeed available (but not accessible) in the subclass's objects. To prove this, here is a sample code with a parent class and a child class and I am writing child class object to a txt file and reading a private member named 'bhavesh' in the file, hence proving it is indeed available in the child class but not accessible due to the access modifier.
import java.io.Serializable;
public class ParentClass implements Serializable {
public ParentClass() {
}
public int a=32131,b,c;
private int bhavesh=5555,rr,weq,refw;
}
import java.io.*;
import java.io.Serializable;
public class ChildClass extends ParentClass{
public ChildClass() {
super();
}
public static void main(String[] args) {
ChildClass childObj = new ChildClass();
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(new FileOutputStream("C:\\MyData1.txt"));
oos.writeObject(childObj); //Writing child class object and not parent class object
System.out.println("Writing complete !");
} catch (IOException e) {
}
}
}
Open MyData1.txt and search for the private member named 'bhavesh'. Please let me know what you guys think.
It would seem that a subclass does inherit the private fields in that these very fields are utilized in the inner workings of the subclass (philosophically speaking). A subclass, in its constructor, calls the superclass constructor. The superclass private fields are obviously inherited by the subclass calling the superclass constructor if the superclass constructor has initialized these fields in its constructor. That's just an example. But of course without accessor methods the subclass cannot access the superclass private fields (it's like not being able to pop the back panel of an iPhone to take the battery out to reset the phone... but the battery is still there).
PS
One of the many definitions of inheritance that I have come across:
"Inheritance -- a programming technique that allows a derived class to extend the functionality of a base class, inheriting all of its STATE (emphasis is mine) and behaviour."
The private fields, even if not accessible by the subclass, are the inherited state of the superclass.
For example,
class Person {
private String name;
public String getName () {
return this.name;
}
Person(String name) {
this.name = name;
}
}
public class Student extends Person {
Student(String name) {
super(name);
}
public String getStudentName() {
return this.getName(); // works
// "return this.name;" doesn't work, and the error is "The field Person.name is not visible"
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Bill");
String name = s.getName(); // works
// "String name = s.name;" doesn't work, and the error is "The field Person.name is not visible"
System.out.println(name);
}
}
Padding bits/Alignment and the inclusion of Object Class in the VTABLE is not considered. So the object of the subclass does have a place for the private members of the Super class. However, it cannot be accessed from the subclass's objects...
I would have to answer that private fields in Java are inherited. Allow me to demonstrate:
public class Foo {
private int x; // This is the private field.
public Foo() {
x = 0; // Sets int x to 0.
}
//The following methods are declared "final" so that they can't be overridden.
public final void update() { x++; } // Increments x by 1.
public final int getX() { return x; } // Returns the x value.
}
public class Bar extends Foo {
public Bar() {
super(); // Because this extends a class with a constructor, it is required to run before anything else.
update(); //Runs the inherited update() method twice
update();
System.out.println(getX()); // Prints the inherited "x" int.
}
}
If you run in a program Bar bar = new Bar();, then you will always see the number "2" in the output box. Because the integer "x" is encapsulated with the methods update() and getX(), then it can be proven that the integer is inherited.
The confusion is that because you can't directly access the integer "x", then people argue that it isn't inherited. However, every non-static thing in a class, be it field or method, is inherited.
No, private fields are not inherited. The only reason is that subclass can not access them directly.
I believe, answer is totally dependent on the question, which has been asked. I mean, if question is
Can we directly access the private field of the super-class from
their sub-class ?
Then answer is No, if we go through the access specifier details, it is mentioned, private members are accessible only within the class itself.
But, if question is
Can we access the private field of the super-class from
their sub-class ?
Which means, it doesn't matters, what you will do to access the private member. In that case, we can make public method in the super-class and you can access the private member. So, in this case you are creating one interface/bridge to access the private member.
Other OOPs language like C++, have the friend function concept, by which we can access the private member of other class.
We can simply state that when a superclass is inherited, then the private members of superclass actually become private members of the subclass and cannot be further inherited or are inacessible to the objects of subclass.
A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass
reference:
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html#:~:text=Private%20Members%20in%20a%20Superclass,be%20used%20by%20the%20subclass.
I can try to help you.
When a subclass(named B, for example) extends a superclass (named A, for example), it automatically inherits fields (such as attributes and/or methods) from its superclass.
Now, B in its Memory Layout has the space for every field in class A even the private ones. The fact is that Java doesn't allow the subclass B to use the private fields because they are private.
As others have pointed out exerpt from JLS:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2:
Members of a class that are declared private are not inherited by
subclasses of that class. Only members of a class that are declared
protected or public are inherited by subclasses declared in a package
other than the one in which the class is declared.
The answer is NO without a doubt, without any iffs and buts. That revolves around the definition of inheritance. By definition inheritance is for classes, not for objects. Objects are created using class definitions. Inheritance is just another block to add to definition of a class. So, does a class inherits any private member of super class? NO
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
Private members (state and behavior) are inherited. They (can) affect the behavior and size of the object which is instantiated by the class. Not to mention that they are very well visible to the subclasses via all the encaptulation-breaking mechanisms that are available, or can be assumed by their implementers.
Although inheritance has a "defacto" definition, it definitely has no link to "visibility" aspects, which get assumed by the "no" answers.
So, there is no need to be diplomatic. JLS is just wrong at this point.
Any assumption that they are not "inherited" is unsafe and dangerous.
So among two defacto (partially) conflicting definitions (which I will not repeat), the only one that should be followed is the one that is safer (or safe).
Suppose that I have two classes A and B and I want to make it so that instances of B can only be created in A and in B itself. I don't want any other class (including subclasses of A) to be allowed to create instances of B. Is there any way of doing this in Java?
Here is a bit of code if it's not clear what I am trying to do:
public class A {
B instance;
public A(){
// Still allows for subclasses to access B
instance = B.getInstance((Object)this);
}
}
Here is the class whose construction I want to limit:
public class B {
// If I make this public all classes can create it, but
// if I make it private without any getter methods then
// no other classes but itself can create it
private B(){}
// Problem with this is that subclasses of A
// can also create instances of B
public static B getInstance(Object o){
if(o instanceof A)
return new B();
else
return null;
}
}
I have tried Googling and searching on StackOverflow for possible solutions, but the closest thing that I have found is using a Singleton design pattern with a modified getInstance() method to make sure only a class with a particular type can have access to instances of class B. While this works fairly well, it still enables any subclass which extends A to get instances of B. Is there any way to stop this from occurring or would it ruin the whole point of subclassing if a subclass couldn't do what its superclass could do?
Suppose that I have two classes A and B and I want to make it so that instances of B can only be created in A and in B itself. I don't want any other class (including subclasses of A) to be allowed to create instances of B.
You could make B a private inner class of the A class.
While this works fairly well, it still enables any subclass which
extends A to get instances of B. Is there any way to stop this from
occurring or would it ruin the whole point of subclassing if a
subclass couldn't do what its superclass could do?
If you don't want your class A to be subclassed, you can make class A final, or can have a private constructor for A. Although as suggested in previous answers,, its better to create private inner classes.
public final class A {
B instance;
public A(){
// Still allows for subclasses to access B
instance = B.getInstance((Object)this);
}
}
A can present something to B that only A can possess. For example
public class A
{
public static class Pass
{
private Pass(){}
Only A can create an A.Pass object. If such objects are only transmitted from A to B, nobody else can get a hold of them and pretend to be A.
public class B
{
public static B getInstance(A.Pass token)
{
if(pass==null)
throw ...
else
caller must be A
This class will throw an exception if creating class is not B
class A {
A() {
new SecurityManager() {
{
if (getClassContext()[1] != B.class) {
throw new IllegalStateException();
}
}
};
}
...
you cannot break it even with reflection
This is the pac.java file
package P1;
public class pac {
int a;
public int b;
private int c;
protected int d;
public pac(){
a=1;
b=2;
c=3;
d=4;
}
public void test(){
System.out.println(a);
System.out.println(b);
System.out.println(c);
System.out.println(d);
}
}
This is other file pack1.java in different package
package P3;
class pac1 extends P1.pac{
public static void main(String args[]) {
pac1 ob=new pac1();
ob.test();
}
}
Question:
How is that possible that from the two files I have shown, the file P3\pac1.java creates an object which access the private variable of the class P1\pac.java?
In Java, a subclass object cannot access private variables (or methods) of any super class.
In your example, pac1 class only access public functionality of class pac, such as the public default constructor & the public method test(). Since the implemnetation of these methods is defined within the super class, both can access its private funvtionality - such as the private int c.
If you override these method in subclass however, the overriding methods implementation won't be able to access class pac private functionality.
HTH.
The method " test() " is inside of the class "pac". Therefore, when you create an instance of pac, the test method belongs to this instance, and can see and use all the variables.
If you had done this, it would have caused an error.
int mainC = ob.c;
the main method (where this is happening) cannot access the variable "c"
What I understand from your unalligned code is that you instantiate a public class and call a public method of it. This is perfectly fine, the test() method has access to variables. You can't access them directly from another method in pac1.
pac1.java only didn't access the private member c of pac.java. It only called the public method test of pac, and that method access the member of the same class.
If I understand you correctly, you are curious how calling ob.test () accesses the private members, despite ob being an object of the derived class. The reason is that whether a method has access is determined at compile time, not run time, and is determined by the location of the method. Your test method is declared in your pac class. So the compiler gives it access to all the private members of the pack class. Now, when it comes to executing the method, it transpires that the type of object your method is executing on is pac1. That does not matter.
This feature of object oriented languages is not a mistake. It makes it possible for the writer of a class to provide limited access to private members, by providing a method that gives only that limited access.
The statement pac1 ob=new pac1(); is creating a new object of Pac1 class and it is possible because it is public.
using ob.test() you are calling a method on the object itself. As private int c is member of the same class in which test() is defined, it can access it.
A private member variable or method is accessible throughout the class in which it is defined.
You can create the object of Pac1 because the class is public.
To clarify your doubt, you cannot access the private member outside the class like this ob.c in the main method.
Consider a very simple example. For a javabean, we make member as private and getter setters as public. We can access them using only getter and setter as they are public.
public class SomeClass{
private int someMember;
public int getSomeMember(){
return this.someMember;
}
}
Now from outside the class,suppose in your main method,
SomeClass someClass = new SomeClass();
someClass.someMember; // This is not possible as we are directly accessing private field
someClass.getSomeMember; // possible because `getSomeMember` is public and it belongs to `SomeClass` so can access private member `someMember`.
`
I tried following piece of program and I came to know we can access default/package level instance variable.
I want to understand why it is allowed in java.
1.
package com.test;
class A {
public int i = 10;
}
2.
package com.test;
public class B extends A{
}
3.
package com.child;
import com.test.B;
public class C extends B{
public int getI(){
return this.i;
}
public static void main(String[] args) {
System.out.println(new C().getI());
}
}
I'm able to run this program successfully. What I want to understand is how it possible to access default access variable from another packkage.
Because it extends B which extends A.
B inherits all public members from A, regardless A's own visibility. That's why C sees the member too.
This is of course quite confusing. The root problem is that a public class extends a non-public class. Maybe the language should forbid that.
there are 4 different access levels: public, private, protected and package-private. Public is visible to everything, outside package even. Private is visible only inside class. Protected is visible to class and to all classes, that extends it. Package-private is default (when you don't specify any of others), and it is visible to all classes within one package, where the variable is initialized
This is an interview question.
Does subclasses inherit private
fields?
I answered "No", because we can't access them using the "normal OOP way". But the interviewer thinks that they are inherited, because we can access such fields indirectly or using reflection and they still exist in the object.
After I came back, I found the following quote in the javadoc:
Private Members in a Superclass
A
subclass does not inherit the private
members of its parent class.
Do you know any arguments for the interviewer's opinion?
Most of the confusion in the question/answers here surrounds the definition of Inheritance.
Obviously, as #DigitalRoss explains an OBJECT of a subclass must contain its superclass's private fields. As he states, having no access to a private member doesn't mean its not there.
However. This is different than the notion of inheritance for a class. As is the case in the java world, where there is a question of semantics the arbiter is the Java Language Specification (currently 3rd edition).
As the JLS states (https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2):
Members of a class that are declared
private are not inherited by
subclasses of that class. Only members
of a class that are declared protected
or public are inherited by subclasses
declared in a package other than the
one in which the class is declared.
This addresses the exact question posed by the interviewer: "do subCLASSES inherit private fields". (emphasis added by me)
The answer is No. They do not. OBJECTS of subclasses contain private fields of their superclasses. The subclass itself has NO NOTION of private fields of its superclass.
Is it semantics of a pedantic nature? Yes. Is it a useful interview question? Probably not. But the JLS establishes the definition for the Java world, and it does so (in this case) unambiguously.
EDITED (removed a parallel quote from Bjarne Stroustrup which due to the differences between java and c++ probably only add to the confusion. I'll let my answer rest on the JLS :)
Yes
It's important to realize that while there are two classes, there is only one object.
So, yes, of course it inherited the private fields. They are, presumably, essential for proper object functionality, and while an object of the parent class is not an object of the derived class, an instance of the derived class is mostly definitely an instance of the parent class. It could't very well be that without all of the fields.
No, you can't directly access them. Yes, they are inherited. They have to be.
It's a good question!
Update:
Err, "No"
Well, I guess we all learned something. Since the JLS originated the exact "not inherited" wording, it is correct to answer "no". Since the subclass can't access or modify the private fields, then, in other words, they are not inherited. But there really is just one object, it really does contain the private fields, and so if someone takes the JLS and tutorial wording the wrong way, it will be quite difficult to understand OOP, Java objects, and what is really happening.
Update to update:
The controversy here involves a fundamental ambiguity: what exactly is being discussed? The object? Or are we talking in some sense about the class itself? A lot of latitude is allowed when describing the class as opposed to the object. So the subclass does not inherit private fields, but an object that is an instance of the subclass certainly does contain the private fields.
No. Private fields are not inherited... and that's why Protected was invented. It is by design. I guess this justified the existence of protected modifier.
Now coming to the contexts. What you mean by inherited -- if it is there in the object created from derived class? yes, it is.
If you mean can it be useful to derived class. Well, no.
Now, when you come to functional programming the private field of super class is not inherited in a meaningful way for the subclass. For the subclass, a private field of super class is same as a private field of any other class.
Functionally, it's not inherited. But ideally, it is.
OK, just looked into Java tutorial they quote this:
Private Members in a Superclass
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
refer: http://download.oracle.com/javase/tutorial/java/IandI/subclasses.html
I agree, that the field is there. But, subclass does not get any privilege on that private field. To a subclass, the private field is same as any private field of any other class.
I believe it's purely matter of point-of-view. You may mould the argument either side. It's better justify both way.
It depends on your definition of "inherit". Does the subclass still have the fields in memory? Definitely. Can it access them directly? No. It's just subtleties of the definition; the point is to understand what's really happening.
I will demonstrate the concept with code. Subclasses ACTUALLY inherit the private variables of super class. The only problem is that they are not accessible to the
child objects unless you provide public getters and setters for the private variables
in the super class.
Consider two class in package Dump. Child extends Parent.
If I remember correctly, a child object in memory consists of two regions. One is the parent part only and the other is the child part only. A child can access the private
section in the code of its parent only via a public method in the parent.
Think of it this way. Borat's father Boltok has a safe containing $100,000. He does not want to share his "private" variable safe. So, he does not provide a key for the safe. Borat inherits the safe. But, what good is it if he cannot even open it ? If only his
dad had provided the key.
Parent -
package Dump;
public class Parent {
private String reallyHidden;
private String notReallyHidden;
public String getNotReallyHidden() {
return notReallyHidden;
}
public void setNotReallyHidden(String notReallyHidden) {
this.notReallyHidden = notReallyHidden;
}
}//Parent
Child -
package Dump;
public class Child extends Parent {
private String childOnly;
public String getChildOnly() {
return childOnly;
}
public void setChildOnly(String childOnly) {
this.childOnly = childOnly;
}
public static void main(String [] args){
System.out.println("Testing...");
Child c1 = new Child();
c1.setChildOnly("childOnly");
c1.setNotReallyHidden("notReallyHidden");
//Attempting to access parent's reallyHidden
c1.reallyHidden;//Does not even compile
}//main
}//Child
No. They don't inherit it.
The fact some other class may use it indirectly says nothing about inheritance, but about encapsulation.
For instance:
class Some {
private int count;
public void increment() {
count++;
}
public String toString() {
return Integer.toString( count );
}
}
class UseIt {
void useIt() {
Some s = new Some();
s.increment();
s.increment();
s.increment();
int v = Integer.parseInt( s.toString() );
// hey, can you say you inherit it?
}
}
You can also get the value of count inside UseIt via reflection. It doesn't means, you inherit it.
UPDATE
Even though the value is there, it is not inherited by the subclass.
For instance a subclass defined as:
class SomeOther extends Some {
private int count = 1000;
#Override
public void increment() {
super.increment();
count *= 10000;
}
}
class UseIt {
public static void main( String ... args ) {
s = new SomeOther();
s.increment();
s.increment();
s.increment();
v = Integer.parseInt( s.toString() );
// what is the value of v?
}
}
This is exactly the same situation as the first example. The attribute count is hidden and not inherited by the subclass at all. Still, as DigitalRoss points out, the value is there, but not by means on inheritance.
Put it this way. If your father is wealthy and gives you a credit card, you can still buy thing with his money, but doesn't mean you have inherited all that money, does it?
Other update
It is very interesting though, to know why the attribute is there.
I frankly don't have the exact term to describe it, but it's the JVM and the way it works that loads also the "not inherited" parent definition.
We could actually change the parent and the subclass will still work.
For instance:
//A.java
class A {
private int i;
public String toString() { return ""+ i; }
}
// B.java
class B extends A {}
// Main.java
class Main {
public static void main( String [] args ) {
System.out.println( new B().toString() );
}
}
// Compile all the files
javac A.java B.java Main.java
// Run Main
java Main
// Outout is 0 as expected as B is using the A 'toString' definition
0
// Change A.java
class A {
public String toString() {
return "Nothing here";
}
}
// Recompile ONLY A.java
javac A.java
java Main
// B wasn't modified and yet it shows a different behaviour, this is not due to
// inheritance but the way Java loads the class
Output: Nothing here
I guess the exact term could be found here: The JavaTM Virtual Machine Specification
Well, my answer to interviewer's question is - Private members are not inherited in sub-classes but they are accessible to subclass or subclass's object only via public getter or setter methods or any such appropriate methods of original class. The normal practice is to keep the members private and access them using getter and setter methods which are public. So whats the point in only inheriting getter and setter methods when the private member they deal with are not available to the object? Here 'inherited' simply means it is available directly in the sub-class to play around by newly introduced methods in sub-class.
Save the below file as ParentClass.java and try it yourself ->
public class ParentClass {
private int x;
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
}
class SubClass extends ParentClass {
private int y;
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public void setXofParent(int x) {
setX(x);
}
}
class Main {
public static void main(String[] args) {
SubClass s = new SubClass();
s.setX(10);
s.setY(12);
System.out.println("X is :"+s.getX());
System.out.println("Y is :"+s.getY());
s.setXofParent(13);
System.out.println("Now X is :"+s.getX());
}
}
Output:
X is :10
Y is :12
Now X is :13
If we try to use private variable x of ParentClass in SubClass's method then it is not directly accessible for any modifications (means not inherited). But x can be modified in SubClass via setX() method of original class as done in setXofParent() method OR it can be modified using ChildClass object using setX() method or setXofParent() method which ultimately calls setX(). So here setX() and getX() are kind of gates to the private member x of a ParentClass.
Another simple example is Clock superclass has hours and mins as private members and appropriate getter and setter methods as public. Then comes DigitalClock as a sub-class of Clock. Here if the DigitalClock's object doesn't contain hours and mins members then things are screwed up.
Ok, this is a very interesting problem I researched a lot and came to a conclusion that private members of a superclass are indeed available (but not accessible) in the subclass's objects. To prove this, here is a sample code with a parent class and a child class and I am writing child class object to a txt file and reading a private member named 'bhavesh' in the file, hence proving it is indeed available in the child class but not accessible due to the access modifier.
import java.io.Serializable;
public class ParentClass implements Serializable {
public ParentClass() {
}
public int a=32131,b,c;
private int bhavesh=5555,rr,weq,refw;
}
import java.io.*;
import java.io.Serializable;
public class ChildClass extends ParentClass{
public ChildClass() {
super();
}
public static void main(String[] args) {
ChildClass childObj = new ChildClass();
ObjectOutputStream oos;
try {
oos = new ObjectOutputStream(new FileOutputStream("C:\\MyData1.txt"));
oos.writeObject(childObj); //Writing child class object and not parent class object
System.out.println("Writing complete !");
} catch (IOException e) {
}
}
}
Open MyData1.txt and search for the private member named 'bhavesh'. Please let me know what you guys think.
It would seem that a subclass does inherit the private fields in that these very fields are utilized in the inner workings of the subclass (philosophically speaking). A subclass, in its constructor, calls the superclass constructor. The superclass private fields are obviously inherited by the subclass calling the superclass constructor if the superclass constructor has initialized these fields in its constructor. That's just an example. But of course without accessor methods the subclass cannot access the superclass private fields (it's like not being able to pop the back panel of an iPhone to take the battery out to reset the phone... but the battery is still there).
PS
One of the many definitions of inheritance that I have come across:
"Inheritance -- a programming technique that allows a derived class to extend the functionality of a base class, inheriting all of its STATE (emphasis is mine) and behaviour."
The private fields, even if not accessible by the subclass, are the inherited state of the superclass.
For example,
class Person {
private String name;
public String getName () {
return this.name;
}
Person(String name) {
this.name = name;
}
}
public class Student extends Person {
Student(String name) {
super(name);
}
public String getStudentName() {
return this.getName(); // works
// "return this.name;" doesn't work, and the error is "The field Person.name is not visible"
}
}
public class Main {
public static void main(String[] args) {
Student s = new Student("Bill");
String name = s.getName(); // works
// "String name = s.name;" doesn't work, and the error is "The field Person.name is not visible"
System.out.println(name);
}
}
Padding bits/Alignment and the inclusion of Object Class in the VTABLE is not considered. So the object of the subclass does have a place for the private members of the Super class. However, it cannot be accessed from the subclass's objects...
I would have to answer that private fields in Java are inherited. Allow me to demonstrate:
public class Foo {
private int x; // This is the private field.
public Foo() {
x = 0; // Sets int x to 0.
}
//The following methods are declared "final" so that they can't be overridden.
public final void update() { x++; } // Increments x by 1.
public final int getX() { return x; } // Returns the x value.
}
public class Bar extends Foo {
public Bar() {
super(); // Because this extends a class with a constructor, it is required to run before anything else.
update(); //Runs the inherited update() method twice
update();
System.out.println(getX()); // Prints the inherited "x" int.
}
}
If you run in a program Bar bar = new Bar();, then you will always see the number "2" in the output box. Because the integer "x" is encapsulated with the methods update() and getX(), then it can be proven that the integer is inherited.
The confusion is that because you can't directly access the integer "x", then people argue that it isn't inherited. However, every non-static thing in a class, be it field or method, is inherited.
No, private fields are not inherited. The only reason is that subclass can not access them directly.
I believe, answer is totally dependent on the question, which has been asked. I mean, if question is
Can we directly access the private field of the super-class from
their sub-class ?
Then answer is No, if we go through the access specifier details, it is mentioned, private members are accessible only within the class itself.
But, if question is
Can we access the private field of the super-class from
their sub-class ?
Which means, it doesn't matters, what you will do to access the private member. In that case, we can make public method in the super-class and you can access the private member. So, in this case you are creating one interface/bridge to access the private member.
Other OOPs language like C++, have the friend function concept, by which we can access the private member of other class.
We can simply state that when a superclass is inherited, then the private members of superclass actually become private members of the subclass and cannot be further inherited or are inacessible to the objects of subclass.
A private class member or constructor is accessible only within the body of the top level class (§7.6) that encloses the declaration of the member or constructor. It is not inherited by subclasses. https://docs.oracle.com/javase/specs/jls/se7/html/jls-6.html#jls-6.6
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass
reference:
https://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html#:~:text=Private%20Members%20in%20a%20Superclass,be%20used%20by%20the%20subclass.
I can try to help you.
When a subclass(named B, for example) extends a superclass (named A, for example), it automatically inherits fields (such as attributes and/or methods) from its superclass.
Now, B in its Memory Layout has the space for every field in class A even the private ones. The fact is that Java doesn't allow the subclass B to use the private fields because they are private.
As others have pointed out exerpt from JLS:
https://docs.oracle.com/javase/specs/jls/se8/html/jls-8.html#jls-8.2:
Members of a class that are declared private are not inherited by
subclasses of that class. Only members of a class that are declared
protected or public are inherited by subclasses declared in a package
other than the one in which the class is declared.
The answer is NO without a doubt, without any iffs and buts. That revolves around the definition of inheritance. By definition inheritance is for classes, not for objects. Objects are created using class definitions. Inheritance is just another block to add to definition of a class. So, does a class inherits any private member of super class? NO
A subclass does not inherit the private members of its parent class. However, if the superclass has public or protected methods for accessing its private fields, these can also be used by the subclass.
Private members (state and behavior) are inherited. They (can) affect the behavior and size of the object which is instantiated by the class. Not to mention that they are very well visible to the subclasses via all the encaptulation-breaking mechanisms that are available, or can be assumed by their implementers.
Although inheritance has a "defacto" definition, it definitely has no link to "visibility" aspects, which get assumed by the "no" answers.
So, there is no need to be diplomatic. JLS is just wrong at this point.
Any assumption that they are not "inherited" is unsafe and dangerous.
So among two defacto (partially) conflicting definitions (which I will not repeat), the only one that should be followed is the one that is safer (or safe).