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).
what's the meaning of "this.this$0" in this code?
what does it stands for?
I know why we use "this" but I have no idea about "this.this$0"
class MainActivity$1 implements TextWatcher
{
public void afterTextChanged(Editable paramEditable)
{
}
public void beforeTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3)
{
}
public void onTextChanged(CharSequence paramCharSequence, int paramInt1, int paramInt2, int paramInt3)
{
this.this$0.ChangeToNumber(paramCharSequence.toString());
}
}
-----------------------or ----------------------
class MainActivity$2 implements View.OnClickListener
{
public void onClick(View paramView)
{
this.this$0.startActivity(new Intent(this.this$0, about.class));
}
}
this.this$0 it's same to Main.access$0
These mysterious symbols usually correspond to the anonymous inner classes. The Java VM doesn't know about them, only about top-level classes, so the Java compiler provides several workarounds to make inner classes to work.
Local class has implicit reference to the instance of its enclosing class,'this$0' corresponds to this reference in the decompiled code.
JVM prevents classes from accessing privates methods of other classes so the compiler generates several synthetic package-private methods like access$0 in order to access private methods of enclosing instance.
There are many others features of the Java language that are implemented with synthetic methods like generics and covariant return types.
I suggest you to check those links:
Decoding Decompiled Source Code For Android
and : Performance Tips
this$0 normally is for the parent object of a non-static inner class. E.g.,
public class Outer {
class Inner1 {
int f1 = 1;
}
static class Inner2 {
int f1 = 2;
}
public static void main(String[] args) {
Outer o = new Outer();
Outer.Inner1 i1 = o.new Inner1(); //weird but valid
Outer.Inner2 i2 = new Outer.Inner2(); //normal
//wrong: Outer.Inner1 i3 = new Outer.Inner1();
}
}
Normally we define inner class as static. i2 has only 1 field, but i1 has an extra this$0 which points to o.
There's nothing preventing you (beside decent naming conventions) from having an instance member called this$0 and then referring to it with the this keyword.
For example :
public class SomeClass
{
int this$0;
public SomeClass (int val)
{
this.this$0 = val;
}
}
The Java 1.1 Language Specification specifies that the name of a type which is a class member, when transformed into Java 1.0 code for the purpose of generating Java virtual machine bytecodes, consists of the fully qualified name of the inner class, except that each .' character following a class name is replaced by a$'. In addition, each inner class constructor receives the enclosing instance in a prepended argument. Here is how the transformed source code of the FixedStack example might look:
public class FixedStack {
... (the methods omitted here are unchanged)
public java.util.Enumeration elements() {
return new FixedStack$Enumerator(this);
}
}
class FixedStack$Enumerator implements java.util.Enumeration {
private FixedStack this$0; // saved copy of FixedStack.this
FixedStack$Enumerator(FixedStack this$0) {
this.this$0 = this$0;
this.count = this$0.top;
}
int count;
public boolean hasMoreElements() {
return count > 0;
}
public Object nextElement() {
if (count == 0)
throw new NoSuchElementException("FixedStack");
return this$0.array[--count];
}
}
Anyone who has already programmed with Java or C++ adapter classes has written code similar to this, except that the link variables must be manually defined and explicitly initialized in top-level adapter classes, whereas the Java 1.1 compiler creates them automatically for inner classes.
When the Enumerator needs to refer to the top or array fields of the enclosing instance, it indirects through a private link called this$0. The spelling of this name is a mandatory part of the transformation of inner classes to the Java 1.0 language, so that debuggers and similar tools can recognize such links easily. (Most programmers are happily unaware of such names.)
(Note: There is a limitation in some implementations of Java 1.1, under which the initialization of this$0 is delayed until after any superclass constructor is run. This means that up-level references made by a subclass method may fail if the method happens to be executed by the superclass constructor.)
I went searching to learn how to do lambda expressions in Java, but instead a confusion came up for me. So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was. Lot of threads and videos I'm seeing seem to call anonymous inner classes just "anonymous classes." Are they synonymous? My understanding of anonymous inner class is:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
So essentially, instead of having to write a subclass for Square, and then override the calculatePerimeter() method, I can just make a one-time square class, and override the method in their. Is this correct?
So, anonymous inner classes have to do with inheritance. I'm not understanding the use of it though. Perhaps, it's because I've never used them before, or because I don't have much programming experience. Can you can give me examples or explain when it's useful?
UPDATE: When I moved my code for the anonymous inner class to an IDE, I learned that there are errors; So apparently, the "square" doesn't even inherit the fields of the rectangle. Doesn't this make it even more useless?
Would the equivalent be:
public class Rectangle {
private double length;
private double width;
private double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
}
public class Square extends Rectangle {
#Override
public void calculatePerimeter() {
perimeter = 4*getLength();
}
public double getLength() {
return length;
}
}
So my understanding of an anonymous class is this:
public class SomeObject {
public static void main(String[] args) {
ArrayList list = new ArrayList();
list.add(new SomeObject());
}
}
There is no anonymous class there. The class SomeObject has a name ... therefore it is not anonymous. In fact, it is just a normal (non-nested, non-inner, non-anonymous) Java class.
I saw the term anonymous inner class before, but at that time, I didn't know what a regular anonymous class was.
There is no such thing as a "regular anonymous class". All Java anonymous classes are "inner".
As the JLS says:
"An inner class is a nested class that is not explicitly or implicitly declared static.
Inner classes include local (§14.3), anonymous (§15.9.5) and non-static member classes (§8.5)."
So, anonymous inner classes have to do with inheritance.
Anonymous inner classes do involve inheritance, but that's not what makes them "inner". See above.
I meant the "list.add(I meant the "list.add(new SomeObject());". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.);". All this time, I thought the object you added to the ArrayList, was called an anonymous class since we didn't name it.
You are incorrect. An object is not a class1.
The new SomeObject() is creating an object, not a class. But that's just normal. Objects / instances don't have names ... as far as the JLS is concerned.
Now variables and fields have names ... but variables are not objects / instances or classes. They are bindings between a name and a slot that can hold a reference to an object (if that's what the type declaration allows).
1 - except in the case of instances of java.lang.Class ... and even then the object is not actually the class / type from a theoretical standpoint.
Or is it called simply an anonymous object and I had two mixed up?
Nope. Objects don't have names. All Java objects are "anonymous". It is not a useful distinction to make. (And see above where I talk about variables ...)
As for your Rectangle / Square examples, they have nothing to do with anonymous classes, inner classes, nested classes or anything like that. They are just top-level classes, using ordinary Java inheritance. (Not that I'm suggesting there is another "non-ordinary" kind of inheritance ...)
First off - square can access fields in Rectangle. You need to mark them protected not private
public class Rectangle {
protected double length;
protected double width;
protected double perimeter;
public void calculatePerimeter() {
perimeter = (2*length) +(2*width);
}
public static void main(String[] args) {
Rectangle square = new Rectangle() {
public void calculatePerimeter() {
perimeter = 4*length;
}
};
}
}
Here are some good descriptions of Inner Classes, Anonymous and local
http://docs.oracle.com/javase/tutorial/java/javaOO/innerclasses.html.
There are two additional types of inner classes. You can declare an inner class within the body of a method. These classes are known as local classes. You can also declare an inner class within the body of a method without naming the class. These classes are known as anonymous classes.
http://docs.oracle.com/javase/tutorial/java/javaOO/localclasses.html
Local classes are classes that are defined in a block, which is a group of zero or more statements between balanced braces. You typically find local classes defined in the body of a method.
http://docs.oracle.com/javase/tutorial/java/javaOO/anonymousclasses.html
http://c2.com/cgi/wiki?AnonymousInnerClass
Anonymous Classes enable you to make your code more concise. They enable you to declare and instantiate a class at the same time. They are like local classes except that they do not have a name. Use them if you need to use a local class only once.
I think the relevance of Anonymous classes comes when you are designing an API. You could create concrete classes to implement every bit of logic for every interface/abstract class but that would create tons of dependencies and you would still be missing some logic. A great example of anonymous classes is when using predicates for filtering. Like in Google Guava
Lets say I have a List<Integer> and I want to filter the numbers remove the 1s and return a new list
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1) rtn.push(i);
}
return rtn;
}
Now lets say I want to filter out 1 and 2
public static List<Integer> filter(List<Integer> input) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(i != 1 && i != 2) rtn.push(i);
}
return rtn;
}
Now lets say 3 and 5s ... this logic is exactly the same except for the predicate check. So we will create an interface
interface FilterNumber {
public boolean test(Integer i);
}
class Filter1s implements FilterNumber {
public Filter1s(){};
public boolean test(Integer i) { return i != 1; }
}
public static List<Integer> filter(List<Integer> input, FilterNumber filterNumber) {
List<Integer> rtn = new ArrayList<Integer>();
for( Integer i : input) {
if(filterNumber.test(i)) rtn.push(i);
}
return rtn;
}
filter(list, new Filter1s());
As you can see with combinations this becomes tedious too. It would be easier to just allow the user of the api to define the logic they want to preform and if it is only needed once just use an anonymous class
filter(list, new FilterNumber() {
#Override
public boolean test(Integer i) {
return i != 1 && i != 3 && i != 7;
}
});
And extending to Lambdas, wouldn't it be even easier to take out all the bloat around i != 1
list.stream().filter( i -> i != 1 )
To answer a later comment, "when I write a new subclass, it inherits those private instance variables. In the case of the anonymous inner class, it didn't."
Subclasses never "inherit" private fields of the superclass (using the JLS terminology). However, subclasses may be able to refer to those private fields anyway, depending on where they're located. If the subclass is declared inside the superclass, or if they're both nested inside the same top-level class, the methods of the subclass can still access the field; assuming you have a source file C.java with just one class C, private fields declared somewhere in C.java are still accessible from most other places in C.java.
However, when testing this, I found some interesting nuances:
class Foo1 {
private int bar1;
public static class Foo2 extends Foo1 {
public void p() {
System.out.println(bar1); // illegal
System.out.println(((Foo1)this).bar1); // works
}
}
}
bar1 is visible, even though it's a private field in the superclass; it's not inherited, but you can access it by telling the compiler to look at the Foo2 object as a Foo1. But just referring to bar1 by itself fails; Java interprets this as an attempt to get the bar1 of the enclosing instance (not the superclass), but Foo2 is static, so there is no enclosing instance.
Note that if Foo2 were declared outside Foo1, the second println would be illegal, because now bar1 is not visible at all, since it's private. The moral here is that "inheritance" and "visibility" (or "access") aren't the same thing. The same thing applies to anonymous inner classes. If you use one in a place where the private instance field is visible, then you can refer to the field; if you use it in a place where the private instance field is not visible, then you can't. The location of the class declaration is more important than the type of class (nested/inner/anonymous) for this purpose.
Suppose we take away the static keyword and make it an inner class:
public class Foo1 {
private int bar1;
public Foo1(int x) {
bar1 = x;
}
public class Foo2 extends Foo1 {
public Foo2(int x) {
super(x * 10);
}
public void show() {
System.out.println("bar1 = " + bar1);
System.out.println("((Foo1)this).bar1 = " + ((Foo1)this).bar1);
System.out.println("Foo1.this.bar1 = " + Foo1.this.bar1);
}
}
}
public class Test64 {
public static void main(String[] args) {
Foo1 f1 = new Foo1(5);
Foo1.Foo2 f2 = f1.new Foo2(6);
f2.show();
}
}
Now a Foo2 object is also a Foo1; but since it's an inner class, a Foo2 instance also has an enclosing instance that is a different Foo1 object. When we create our Foo2, it users a superclass constructor to set the superclass bar1 to 60. However, it also has an enclosing instance whose bar1 is 5. show() displays this output:
bar1 = 5
((Foo1)this).bar1 = 60
Foo1.this.bar1 = 5
So just bar1 by itself refers to the field in the enclosing instance.
public class Parent {
public enum ChildType {
FIRST_CHILD("I am the first."),
SECOND_CHILD("I am the second.");
private String myChildStatement;
ChildType(String myChildStatement) {
this.myChildStatement = myChildStatement;
}
public String getMyChildStatement() {
return this.myChildStatement;
}
}
public static void main(String[] args) {
// Why does this work?
System.out.println(Parent.ChildType.FIRST_CHILD.myChildStatement);
}
}
Are there any additional rules with regard to access control for Parent subclasses, classes within the same package, etc., in reference to this enum? Where might I find those rules in the spec?
It has nothing to do with it being an enum - it has everything to do with private access from a containing type to a nested type.
From the Java language specification, section 6.6.1:
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.
For example, this is also valid:
public class Test {
public static void main(String[] args) {
Nested nested = new Nested();
System.out.println(nested.x);
}
private static class Nested {
private int x;
}
}
Interestingly, C# works in a slightly different way - in C# a private member is only accessible within the program text of the type, including from any nested types. So the above Java code wouldn't work, but this would:
// C#, not Java!
public class Test
{
private int x;
public class Nested
{
public Nested(Test t)
{
// Access to outer private variable from nested type
Console.WriteLine(t.x);
}
}
}
... but if you just change Console.WriteLine to System.out.println, this does compile in Java. So Java is basically a bit more lax with private members than C# is.
Because the enum is effectively an inner class of the parent.
A top level class is like a village, everybody knows everybody, there are no secrets. Nested units within it don't change that fact.
class A
private a;
class B
private b
a = x; // ok
new B().b = y; // ok
class C extends A{}
new C().a = z; // ok
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).