This question already has answers here:
Do subclasses inherit private fields?
(21 answers)
Closed 8 years ago.
I've read in a textbook that class members that are marked as private are not inherited.
So I thought if class A has a private variable x and class B would extend class A then there would be no variable x in class B.
However a following example shows that I misunderstood that:
public class testdrive
{
public static void main(String[] args) {
B b = new B();
b.setLength(32);
System.out.print(b.getLength());
}
}
class A {
private int length;
public void setLength(int len) {
length = len;
}
public int getLength() {
return length;
}
}
class B extends A {
public void dummy() {
}
}
The result is 32 and I'm confused because it looks like object with ref b now has the variable length and it's value is 32. But ref b refers to object created from class B where the length variable is not defined.
So what's the truth, does class B inherit the private variable length? If so, what does it mean that private variables are not inherited?
The field that is private is hidden in B. But, your public methods are inherited and are accessible, and they can access the private field.
Hey man it's not how you think it is, private fields can only be accessed by the methods present in the same class (given ofcourse that the methods are accessible from other class)
its not that you can directly call:
b.length=8;
Or you cannot even do this:(write this where you created the object for B)
A a = new A();
a.length=8;
both of these approach are invalid!
For more info:
you don't even need to extend B from A, just create an object of A in main and use those get and set methods of yours and it will work too!
You don't have direct access to the private fields and method of a superclass but you are able to access them through the use of other public methods.
This is one of the fundamental concepts of the Object-Oriented Programming and it's named Encapsulation.
Read more about this here : TutorialsPoint.
Bottom-line : You can't directly access a private field or method like this
b.length = 32;
nor like this (for the superclass)
A a = new A();
a.length = 32;
but you can manipulate those fields through the use of a public method like in your example.
The reason is simple : your private fields/methods are hidden for other classes except for the class which holds them , but your public fields/methods are not hidden.
Related
This question already has answers here:
Why can an instance of a class access private fields of another instance of its own type?
(3 answers)
Closed 1 year ago.
Usually, if type is a private member of a class named Pass, and obj is a reference to object of Pass class, we cannot do obj.type because type is private member so that would give error.
In copy() method, a is passed as a parameter where a is a reference to Pass object.
By the same logic, we should also not be allowed to do a.type.
But this code runs fine. Why? This is my doubt.
public class Main {
public static void main(String[] args) {
Pass ob1 = new Pass(10,'c');
Pass ob2 = new Pass(20,'f');
ob1.print();
ob2.print();
ob1.copy(ob2);
ob1.print();
ob2.print();
}
}
class Pass {
private int number = 0;
private char type = 'a';
public Pass(int i, char t) {
this.number = i;
this.type = t;
}
public void copy(Pass a) {
this.number = a.number;
this.type = a.type;
}
public void print() {
System.out.println(number + " =>" + type);
}
}
There are four types of Java access modifiers:
Private: The access level of a private modifier is only within the class. It cannot be accessed from outside the class.
Default: The access level of a default modifier is only within the package. It cannot be accessed from outside the package. If you do not specify any access level, it will be the default.
Protected: The access level of a protected modifier is within the package and outside the package through child class. If you do not make the child class, it cannot be accessed from outside the package.
Public: The access level of a public modifier is everywhere. It can be accessed from within the class, outside the class, within the package, and outside the package.
In your case, you access the type variable inside the Pass class. So even though it is a private variable, you have permission to access it.
Because the method is in the same class, it can access private members of other instances. private only means that only functions in the class can access it, with no restrictions on which object is doing the accessing.
I'm having trouble trying to implement this statement I read in Oracle's Docs about Inheritance when it comes to inner classes.
The statement :
A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
In order to test this out i.e. to see if I can achieve the above I created a top level class OC1 which had an inner class IC1 ,then I created another top level class OC2 which extended IC1.
Before I could even start writing a single method , the IDE stopped me at the OC2 class body itself saying
"No enclosing instance of type DataStructure is available due to some intermediate constructor invocation"
I read some other answers and most of them point to either
a) Changing the inner class to static Nested Class -- it resolves the error
b) The whole scenario is unnecessary and convoluted.
Here is the code:
public class DataStructure {
// Create an array
private final static int SIZE = 15;
private int[] arrayOfInts = new int[SIZE];
public DataStructure() {
// fill the array with ascending integer values
super();
for (int i = 0; i < SIZE; i++) {
arrayOfInts[i] = i;
}
}
//other methods
//IC1
protected class instanceArr{
private int a = 8;
private static final int B = 4;
protected instanceArr(){
}
protected void doSomething(){
System.out.println("arrayOfInts[] is accessible " + arrayOfInts[6]);
}
}
//main method
}
OC2
public class DataStructureChild extends DataStructure.instanceArr{
public DataStructureChild(){
}
}
I know that the scenario is not an ideal one but I don't want to change inner class to static nested class - it would defeat my purpose of basically trying to see whether arrayOfInts is accessible without OC1's instance in hand.
Am I misinterpreting this statement ? if not then kindly point me in the correct direction.
PS - this is my first question here - apologies in advance if some guidelines were flouted.
Yes, this is a Trap caused by Java's synthetic sugar. You think the inner-non-static-class have the default-no-arguments-constructor but that is wrong. Internally the constructor of IC1 have the OC1 as first argument in the constructor - even if you can not see it.
Thats why the OC2 constructor must use the OC1 as constructor-argument:
public DataStructureChild(DataStructure argument) {
}
Unfortunaltely this is not enougth, you need to get sure the argument is not-null:
public DataStructureChild(DataStructure argument) {
argument.super();
}
It looks very wierd but it works.
You can do this since you inherit access to the inner class of the parent.
class DataStructureChild extends DataStructure {
public DataStructureChild() {
}
public void foo() {
InstanceArr ins = new InstanceArr();
ins.doSomething();
System.out.println(ins.a);
}
}
But could you please give a link or explain where you read the following? A nested class has access to all the private members of its enclosing class—both fields and methods. Therefore, a public or protected nested class inherited by a subclass has indirect access to all of the private members of the superclass.
The first part I knew about. But I never considered a separate class extending another classes inner class. Especially since there is usually an implicit relationship between classes and their enclosed inner classes.
Edit:
I believe you misunderstood the statement.
It says that your subclass inherits the inner class. That is true.
It also says that once done you have access to the private values of the inherited inner class. That is also true as demonstrated above:
So it was just talking about access the inner class via inheritance, not extending it directly.
However, if you really want to do have that kind of inheritance relationship without passing references around, you can go this route.
public class Inheritance extends Outer.Inner {
public Inheritance() {
new Outer().super();
}
public static void main(String[] args) {
new Inheritance().start();
}
public void start() {
System.out.println(a);
method();
}
}
class Outer {
public Outer() {
}
protected class Inner {
protected int a = 10;
protected Inner() {
}
protected void method() {
System.out.println("This is a private message");
}
}
}
This question already has answers here:
Private methods in Inheritance
(9 answers)
Closed 7 years ago.
A friend of mine asked this question to me. Why the following code does not give error on invoking aa.x()?
I understand that aa is a reference to object of class B but is invoking private method of class A inside the method of class A where it is visible and hence accessible.
Is my understanding correct? Or is there any other reason behind this?
public class A {
public void xyz() {
System.out.println("A");
}
private void x() {
System.out.println("A:x");
}
public static void main(String[] args) {
B b = new B();
A aa = b;
aa.x();
aa.xyz();
B bb = (B) aa;
bb.xyz();
bb.xyz12();
}
}
class B extends A {
public void xyz() {
System.out.println("B");
}
public void xyz12() {
System.out.println("B-12");
}
}
I can't immediately find a duplicate using a subclass, but fundamentally it's the same answer as the answer to this question.
There are two things that govern access to x:
Where the code is that's doing the access. Since x is private to A, the code accessing it must be part of a method in A. It can't be in a subclass (B) or an unrelated class.
What kind of reference you're using. If you have an A reference, you can access x on it. If you have a B reference, you can't, even though your code is part of an A method. You could cast it to A and then access x, but you can't do it directly with a reference of type B.
It is only visible because the main method where it is invoked is contained in class A. Move it to class B and it will not work
As the private methods are not inherited, a superclass reference calls its own private method.
Your main method is the method of A, therefore it can can call x() private method.
private modifier—the field is accessible only within its own class.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Is it possible in Java to access private fields via reflection
Is there any way so that we can call the private data members of a class in java, can be accessed outside the class.
I want this for a tricky question banks.
As much my java experience i think this is possible, but i don't know how to do it.
1) You can do it with reflection, if SecurityManager allows
class B {
private int x = 2;
}
public class A {
public static void main(String[] args) throws Exception {
Field f = B.class.getDeclaredField("x");
f.setAccessible(true);
f.get(new B());
}
}
2) in case of inner classes
class A {
private int a = 1;
class B {
private int b = 2;
private void xxx() {
int i = new A().a;
};
}
private void aaa() {
int i = new B().b;
}
As per the java language specification, 3rd edition:
6.6.8 Example: private Fields, Methods, and Constructors
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.
You can use reflection in java to access private fields. Ideally, you should be using public setters and getter methods to access such data from outside the class (as others have posted)
for more info about access modifiers check below link
http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html
and this for Accessing private variables in Java via reflection
Accessing private variables in Java via reflection
No private member can't be used outside the class
You can use getter and setter methods for this purpose
You can do it using public methods that returns/set the private field value.
public Class A{
private String myData;
public String getMyData(){
return myData;
}
public void setMyData(String data){
this.myData=data;
}
}
Define a public get method to get private field of your class.
No you cannot, by any means access the private variables in java.
You can provide public getter and setter methods to access or change the value of the private member variables.
Before you start reading I would like to clarify:
I have already thought of other designs and work arounds
I'm only interested in the problem I exposed and not "changing" it (so no solutions such as delete the points in A and create new points fields in B and C...
lets consider the following code:
public class A {
protected cpVect[][] points = null;
...
}
and its classes that inherits it:
public class B extends A{
...
}
public class C extends A{
...
}
so far so good.
my problem is that for B and C contains arrays of points that will be created in the constructor using something like
if(points == null){calculate points code}
the problem is as follow
points in A can't be static because the dimensions are different in B and C.
but every instance of B will share the B points and every instance of C will share the C points. (in other words a Square will always be a square and a triangle will always be a triangle). and therefore I want to have the B:points and C:points static so that i don't get duplicates of the values for every instance.
So is there a way to redefine points as static in B and C when it is not static in A?
If you access points solely through property methods (getters/setters) you can do whatever you want in the subclasses. If you use inheritance, A will have to be an abstract class. Otherwise you'd always carry around the empty points variable in A (losing 8 bytes, probably).
In this case the hierarchy would look like this:
abstract class A {
abstract public cpVect[][] getPoints();
// more methods ...
}
public class B extends A {
private final static cpVect[][] POINTS = calculatePoints();
#Override
public cpVect[][] getPoints() {
return POINTS;
}
private cpVect[][] calculatePoints() {
// ...
}
}
And the same for C. If A includes no other state or functionality, you should make it an interface.
You can't make the field static, but you could make it a singleton. You'll have multiple references to the singleton, but you'll only need one copy of each points array. For example, in B:
class B extends A {
private cpVect[][] B_points = null;
public B() {
if (B_points == null)
B_points = create_B_points();
points = B_points;
}
}
If multithreaded, you'll need to add synchronization.
(Sorry for earlier half-finished version. The SO editor seems quirky in Chrome).
There is no significance of static and non-static in inheritance. ie if you have a member variable in a parent class then you can have the same name for the static member of the child class. as shown
class test {
public int a;
}
class test1 extends test {
public static int a;
}
And through objects you can access a of test.
through class test1 you can access static a of test1. as both are independent.
You cannot have a same variable as the member in parent and static in child.