Using a private variable in a inherited class - Java - java

Need to have more understanding about the private variables and inheritance. Earlier my understanding was if there is field in a class and when I'm inheriting the class, the fields that is not restricted by access(private variables) will be there in the inherited class. But I'm able use the private variables in base class if there is a public g/setter method.
How can I imagine a private variable in a base class.?

class A {
private int a;
public A(int a) { this.a = a; }
public int getA() {return a;}
}
class B extends A {
public B(int b) { super(b); }
public int getB() {return getA();}
}
int result = new B(10).getA();
result will be 10. Private field a in class A is kind of inherited to B but B can't access it directly. Only by using the public/default/protected accessor methods defined in class A. B is A so it always has all the same fields that are in A and possible some new fields defined in class B.

This is what Java tutorial http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html says:
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.
Nevertheless, see this
class A {
private int i;
}
class B extends A {
}
B b = new B();
Field f = A.class.getDeclaredField("i");
f.setAccessible(true);
int i = (int)f.get(b);
it works fine and returns value of field i from B instance. That is, B has i.

private variables / members are not inherited. That's the only answer.
Providing public accessor methods is the way encapsulation works. You make your data private and provide methods to get or set their values, so that the access can be controlled.

Related

java initialize base class fields in subclass constructor

This is a very basic question about subclasses in java, I still don't get it...
Suppose I have a superclass with three fields and with only the default constructor:
public class Superclass {
public int a;
public int b;
public int c;
}
and I want to add a field x. I cannot change Superclass, so I make a subclass:
public class Subclass extends Superclass {
public int x;
public Subclass(Superclass s) {
super();
// what to do??
}
}
I now want to generate a Subclass object from an existing Superclass object:
Superclass s = new Superclass();
s.a = "a";
s.b = "b";
Subclass sc = new Subclass(s);
sc.x = "x";
such that I can still access sc.a, sc.b etc.
How can I best do this without assigning all these fields 'by hand' in the constructor of the subclass?
You have to assign a value to the variables either in the base-class constructor or in the child class.
You can declare a parameterized constructor in sub-class to assign the value to a variable in the superclass
class Subclass extends Superclass {
public int x;
public Subclass(int a,int b, int c,int x) {
super();
this.x = x;
this.a=a;
this.b=b;
this.c=c;
}
}
Or you can declare a parameterized constructor in BaseClass, and in child class, instead of calling super(), call that parametrized constructorsuper(a,b,c)
class Superclass {
public int a;
public int b;
public int c;
public Superclass(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
}
class Subclass extends Superclass {
public int x;
public Subclass(int a,int b, int c,int x) {
super(a,b,c);
this.x = x;
}
}
Other than copying by hand you can't.
Java is not JavaScript where objects are prototypes of other objects, instead in Java, classes subclass other classes.
I now want to generate a Subclass object from an existing Superclass
object
In fact no, you will instantiate a Subclass object by relying on the state of a Superclass object.
As you pass the SuperClass as parameter of the Subclass constructor, you just need to use fields of it to invoke the super constructor if you declare it :
public Subclass(Superclass s) {
super(s.a, s.b, s.c); // constructor may simplify
}
Or if you have a super constructor with no arg :
public Subclass(Superclass s) {
a = s.a;
b = s.b;
c = s.c;
}
Note that in Java using the private modifier for instance fields is strongly encouraged and you should access to field via public methods.
A cleaner way for your constructor would look like :
public SuperClass(int a, int b, int c) {
this.a = a;
this.b = b;
this.c = c;
}
public Subclass(Superclass s) {
super(s.getA(), s.getB(), s.getC()); // constructor may simplify
}
If you truly cannot change the superclass, then the only way you can inspect and modify the values of the member variables is by using reflection.
You should note that if getters and setters aren't exposed to subclasses (i.e. they are private) then there's a question of whether the original creator of class wanted you to ever have access to the contained variables in the first place. Would your assignments change the behaviour of the parent in an unpredictable/unsupported way?
If the SuperClass is of your own design, then you should ensure that you always use getters and setters so that you may define the proper protocol (way to interact) with your class unambiguously. This rule also applies for the visibility of class constructors. Generally speaking, every member variable of a class should be possible to initialize via a class constructor; whether that constructor is visible, or exposes all of the possible parameters to subclasses or upon allocation by external sources, is a different story.

How to get attributes of a parent class in Java?

How do I get the attributes of Class A, a parent class (super class), to use it in Class C in Java.
For instance:
Class B extends A
Class C extends B
You need to declare the member protected:
public class A
{
protected int myInt = 5;
}
public class B extends A
{
}
public class C extends B
{
public int GetInt()
{
return myInt;
}
}
private member can be accessed only by the class itself, protected by the class and all the derived classes.
Typically it is best to keep attributes private, and access them via accessor (getter) and mutator (setter) methods from any other class, including derived classes. If the variable must or should be accessed directly from subclasses, which occasionally is desirable but not usually, then nearly always declare it protected.

How to use values of local variables in inherited functions of java? [duplicate]

This question already has answers here:
Java Inheritance - instance variables overriding
(3 answers)
Closed 7 years ago.
I have 2 classes A and B such that
public class A {
public String a = "hey";
public void printA() {
System.out.println(a);
}
and
public class B extends A{
public String a = "Jude";
}
What do I need to do so that the output of the lines below is Jude
B object = new B();
object.printA(); //This should output Jude
You cannot access the subclass field from the superclass. However you can change it in subclass like this:
public class B extends A {
B() {
this.a = "Jude";
}
}
This way you don't declare the new field, but change the value of existing one. Note that extends A is necessary to specify that B is subclass of A.
Alternatively you may consider using a method instead of field:
public class A {
public String getA() {
return "hey";
}
public void printA() {
System.out.println(getA());
}
}
public class B extends A {
#Override
public String getA() {
return "Jude";
}
}
Note that in Java "variable" term usually applied to local variables declared within methods. You are speaking about "field", not "variable".
Fields can not be overridden. Methods can; use methods instead:
public class A {
public String getA() {
return "hey";
}
public void printA() {
System.out.println(getA());
}
}
public class B extends A {
public String getA() {
return "Jude";
}
}
That's all. If getA() is not called outside these classes, cincdider making it protected.
Just change your declaration of a to this.a like so.
public class B extends A{
B(){
super();
//Could hardcode this.a to "Jude" here if you want.
}
B(String word){
super();
this.a = word;
}
}
a is already defined for B from the superclass A so you need to use "this" to access it.
You can use it like so
B object = new B("Jude");
object.printA(); //"Jude"
The Java® Language Specification, Java SE 8 Edition
If the class declares a field with a certain name, then the
declaration of that field is said to hide any and all accessible
declarations of fields with the same name in superclasses, and
superinterfaces of the class.
Not sure If I need to further explain it for the audience, but YOU CANNOT "use values of local variables in inherited functions of java", why? See above.

Why have I no access to the protected field?

I am learning about access levels in java and I have created 3 classes:
In package my.inheritance
I have class A and class C
package my.inheritance;
public class A {
protected int a=15;
}
package my.inheritance;
public class C {
public static void main(String[] args)
{
A a = new A();
System.out.println(a.a);
}
}
And in another package called my.inheritance.test I have a class B trying to access protected field of int value a but the compiler complains for this!
package my.inheritance.test;
import my.inheritance.A;
public class B extends A{
public static void main(String[] args)
{
A a = new A();
int value = a.a;
System.out.println(value);
}
}
I was under the impression with protected you can access a member from a different class in a different package as long as you subclass it! Why the visibility error then ?
Every method can access protected fields of its own class, and all its parent classes. This does not include access to protected fields of another class, even if they have the corresponding base class in common.
So methods in class B can access protected fields from objects of class B, even if they were declared in A, but not from some other object of class A.
One could say that class B inherits the protected members from A, so now every B has those members as well. It doesn't inherit access to the protected members of A itself, so it cannot operate on protected members of any A but only on those of B, even if they were inherited from A.
Try:
public class B extends A
{
public static void main(String[] args)
{
B a = new B();
int value = a.a;
System.out.println(value);
}
}
You can access a only if it is in the same object.
1. protected is an access modifier which is used when you want to have an access outside the package.
2. Most people try to access the protected member of the Super class by creating and Object reference variable of the Super class, and then using dot operator to access that protected member.... But thats WRONG.
3. We get access to the inherited member of the Super class Not the direct member of the super class.
Eg:
package com.demo1;
public class A{
protected int a = 5;
}
package com.demo2;
public class B extends A{
public static void main(String[] args){
System.out.println(new B().a); // This "a" is the inherited member
}
}
4. And one more important point, This inherited "a" member in the sub-class, will be seen by the another class in the same package that of the sub-class as a private member.. So consider that another class in this package can't even see this protected memeber...
You have access to this field from B using this.a because B extends A, but in this case you are trying to access to this field througth an instance of A, this is limited by the protected access.
What you're trying to do is:
A a = new A();
int value = a.a;
Note that a.a is a qualified name, and in this case you can call it in body of a class B only if the type of the expression to the left of . is B or it's subclass.
Relevant part of JLS

Can I make a protected member public in Java? I want to access it from a subclass

I'm new to Java and OOP,
I was using a private subclass (actually a struct) B in a class A, and everything went well until I decided to make a parent class C for subclass B. I want make public some of the protected members of class C.
For example:
public class A {
private class B extends C {
public int product;
public int x;
public int y;
public void add() {
product=x+y;
}
}
B b=new B;
b.x=1;
b.y=2;
b.multiply();
System.out.println(b.product+"="+b.x+"x"+b.y);
public class C {
protected int x;
protected int y;
public int sum;
public C(px,py) {
x=px;
y=py;
}
public void sum() {
sum=x+y;
}
}
And I get
Implicit super constructor C() is undefined for default constructor.
Must define an explicit constructor
Of course, I could remove extends C, and go back to what I had before. Or I could make a getter/setter. But I think it is understandable that an inner struct is acceptable, and it should be able to extend other classes.
The compiler message is reasonably clear - in B you've effectively got:
public B() {
super();
}
and that fails because there's no parameterless constructor in C to call. Either introduce a parameterless constructor, or provide an explicit constructor in B which calls the constructor in C with appropriate arguments.
I'm not sure it's a good idea to have all these non-private fields, mind you - nor is it a good idea for fields in B to hide fields in C. Do you really want an instance of B to have two x fields and two y fields? You realise they will be separate fields, don't you?
If you just want to effectively provide public access, you could have:
public void setX(int x) {
this.x = x;
}
public int getX() {
return x;
}
(and the same for y) and remove the extra fields from B. You can't change the actual accessibility of the fields in C though.
Okay, I was fuddling with my own code and found that the problem is I needed a protected default constructor for superclass C. It works now...

Categories