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).
I was trying to test working of private interfaces and wrote the code below. I can understand that a situation might arise to declare private interfaces if we don't want any other class to implement them but what about variables? Interface variables are implicitly public static final and hence i was able to access them even if interface was declared private. This can be seen in code below.
public class PrivateInterfaceTest {
/**
* #param args
*/
public static void main(String[] args) {
TestingInterfaceClass test = new TestingInterfaceClass();
TestingInterfaceClass.inner innerTest = test.new inner();
System.out.println(innerTest.i);
}
}
class TestingInterfaceClass {
private interface InnerInterface {
int i = 0;
}
class inner implements InnerInterface {
}
}
Does it mean that we can never really have private interface in true sense? And does it really make sense to if have private interface if we can access variables outside private interface?
EDIT:
Just want to add that same situation will not arise if we have private inner class. A private variable in inner class will never get exposed.
Your member interface is private. The inherited static field is not private.
A private member interface cannot be used as a type outside the enclosing top-level class or enum. This can be useful to prevent external code from implementing an interface you may wish to change. From the JLS:
The access modifiers protected and private pertain only to member interfaces within a directly enclosing class or enum declaration (§8.5.1).
The interface field is public, and inherited by the class that implements the interface. From the JLS:
A class inherits from its direct superclass and direct superinterfaces all the non-private fields of the superclass and superinterfaces that are both accessible to code in the class and not hidden by a declaration in the class.
If you want to make the field accessible only within the classes that implement the member interface, you can put its declaration in the enclosing top-level scope.
class TestingInterfaceClass {
private static final int i = 0;
private interface InnerInterface {
// ...
}
class inner implements InnerInterface {
// ...
}
}
As I see, it is not the problem with private interface InnerInterface. It is the inner class which is at default scope inside TestingInterfaceClass exposing the content of InnerInterface. If you don't want the content of InnerInterface to be known to the world, you should also declare all the classes (specifically TestingInterfaceClass) as private.
Because every variable in an interface is public static final, it should be the responsibility of the class (implementing it) whether it should take care of the content inherited from private interface
Even though it's allowed, we don't need (and shouldn't use) an instance to access an static field.
Following is the way to access it -
System.out.println(TestingInterfaceClass.inner.i);
//note you cannot access the InnerInterface like this here because it's private
The inner has inherited the public static field i and i should be visible wherever the inner itself is visible.
Usually, interfaces are used to expose the behaviors of an object, while the implementations are hidden. But in your case, you are attempting the opposite.
The Interface variables are implicitly public static final, but you can't reach this variables because you can't reach previously the interface that contains these variable, which you have declared as private. First you need to be able to see the interface, and after that, go into content of the interface.
I am fairly new to the concept of abstract data types an was looking for clarification because I could not find any good examples online.
From my understanding, the sub class inherits all methods and variables from the abstract but I think I am misunderstanding this. For example, I am creating a menu using the abstract data type MenuItem
import javax.swing.*;
public abstract class MenuItem{
private String itemName;
private int ct;
private double costPer;
public String getItemName()
{
return itemName;
}
public int getCt()
{
return ct;
}
public double getCostPer()
{
return costPer;
}
}
public class Hamburger extends MenuItem{
itemName = "Hamburger";
ct = 0;
costPer = 4.99;
}
I know this is incorrect but can someone tell me why? Does the subclass hamburger only inherit the methods or what?
There are several issues:
itemName et al are private, so even though they're inherited, they're not visible to the subclass.
The syntax you use in Hamburger is invalid.
Here is how you could fix your code:
public abstract class MenuItem{
public MenuItem(String itemName, int ct, double costPer) {
this.itemName = itemName;
this.ct = ct;
this.costPer = costPer;
}
...
}
public class Hamburger extends MenuItem{
public Hamburger() {
super("Hamburger", 0, 4.99)
}
}
Finally, I'd say that instead of using an abstract base class and a bunch of concrete classes, it would be better to use a single concrete class for MenuItem and make Hamburger etc instances of that class.
The problem lies in the visibility of the fields in your MenuItem parent class. private visibility means, that they are not visible to any other class including own subclasses.
In oreder to make your fileds visible to subclasses, you have to change their visibility to protected. Be aware that this makes the fields visible to all classes in the same package as well.
All the memeber visibility issues are covered in greater detail in this article
From my understanding, the sub class inherits all methods and variables from the abstract but I think I am misunderstanding this
yes, your understanding about your mis-understanding is correct. :-)
sub classes in java do not inherit the private member variables. they get public and protected members only.
itemName, costPer and ct are declared as private access fields. They are only accessible from within the class they are defined in. If you declare them with protected access, you'll be able to access them.
As defined in the Java Language Specification, section 6.6 Access Control
A member (class, interface, field, or method) of a reference (class, interface, or array) type or a constructor of a class type is accessible only if the type is accessible and the member or constructor is declared to permit access:
...
(Otherwise,) if the member or constructor is declared private, then access is permitted if and only if it occurs within the body of the top level class (§7.6) that encloses the declaration of the member or constructor.
...
Before you start looking into abstract types, start with the concept of encapsulation, and try to understand it as it is considered (by many) as the most important concept in the object-oriented design, followed by polymorphism, and inheritance. If class members are private, no subclass will be able to access them directly.
Yes, Hamburger only inherits the methods. That's because they're public. If you made them private (like the fields) they wouldn't be inherited either. Here's how to fix the problems.
import javax.swing.*;
public abstract class MenuItem {
//To be visible to subclasses, these need to be public, package-private, or protected
protected String itemName;
protected int ct;
protected double costPer;
public String getItemName() {
return itemName;
}
public int getCt() {
return ct;
}
public double getCostPer() {
return costPer;
}
}
public class Hamburger extends MenuItem {
//These assignments need to be inside a block, like a constructor
public Hamburger() {
itemName = "Hamburger";
ct = 0;
costPer = 4.99;
}
}
An abstract class can never be instantiated. Its sole purpose is to be extended. In an abstract class, if you specify atleast one method as abstract, then the whole class needs to be specified as abstract. An abstract class allows you to have implemented and unimplemented (abstract) methods all in the same class. If all methods in the class are abstract, then you effectively have a interface, and any variables declared in an interface are treated as constants. The variables in your question are not inherited as they are private to the abstract class. You must access them through the methods of the abstract class.
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).
Why do we need constructors and private members in the abstract class? It is not like we are ever going to create an instance of that class.
You will create instances, just instances of a derived class. Those derived classes will still need to call constructors, and can still call members of the abstract class - which may in turn use private members.
Here's an example (not a terribly useful one, but just to show the basic idea...)
public abstract class NamedObject
{
private final String name = name;
protected NamedObject(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
public class Computer extends NamedObject
{
private final int processorSpeed;
public Computer(String name, int processorSpeed)
{
super(name); // See, the constructor is useful
this.processorSpeed = processorSpeed;
}
public String toString()
{
return getName() + " (" + processorSpeed + ")";
}
}
I can't say I write abstract classes that often, generally preferring composition to inheritance, but when I do create them I certainly use constructors and private members.
Abstract classes provide a partial implementation of some interface. It's perfectly reasonable to consider that you might want to provide part of that implementation and disallow client code (concrete subclasses) from accessing the specifics - i.e. an extension of the principle of encapsulation.
Marking some members as private forces the inheriting class to call protected methods to access that partial implementation; providing a constructor allows for subclasses to initialise the parent's encapsulated state during their own construction.
Unlike an interface, an abstract class that defines data fields is in fact instantiated in the sense that these data fields are allocated. It is just that they are never instantiated on their own, they are instantiated as part of something bigger - the subclass. So when the subclass is built, the supertype is built as well, which is why you would need a constructor.
Depending on your hierarchy, your abstract class may have a meaning and state. For example, if your application is a school you may have the notion of a person (that has a name and an SSN), but you would have different subtypes for students and for faculty. Because both types of people share certain state structure (name and SSN) you would have both classes extend the Person class. But you would never simply instantiate a person directly.
In addition to Jon's answer, I'd like to mention that abstract classes still go well with composition, if you keep the subclass tree shallow. I.e. it is great for providing a common base class for a few closely related objects, but not for creating a gigantic tree of subclasses.
Why do you need private class? I think that you are confusing abstract classes with interfaces. Unlike interfaces, abstract classes can hold functionality. For example:
public class AbstractBase{
private int num;
public AbstractBase(int number){
this->num = number;
}
public int method(){
return ( this->num * this->templateMethod());
}
public abstract int templateMethod();
}
public class ConcreteDerived extends AbstractBase{
public ConcreteDerived(){
super(4);
}
public int templateMethod(){
return number; //number is the result of some calculation
}
}
In this example, you´ll never explicitly instantiate AbstractBase, but by declaring members and constructors, you can customize the functionality of your classes (this is called template method).
Assuming you're doing ad hoc code or prototyping, you do instantiate abstract classes (or maybe even interfaces) from time to time. They're called anonymous inner classes (one, two) and look like this:
// you have this...
public abstract class SomeClass {
public abstract String returnAString();
}
// ...and this...
public class OtherClass {
public void operate(SomeClass c) {
System.out.println(c.returnAString());
}
}
// ...so you do this:
OtherClass oc = new OtherClass();
// this is one of the reasons why you need to specify a constructor
oc.operate(new SomeClass() {
#Override
public String returnAString() {
return "I'm an anonymous inner class!";
}
});
This example is of course quite redundant but should expose the point. Some existing frameworks even rely on the heavy usage of this behaviour, namely Apache Wicket at least.