i know that constructors are not inherited in java and we have to implicitly or explicitly call them and private instance variables only accessible within the class's that they are declared.
assume that we have a superclass with one private instance variable and we initialize it with superclass constructor
for example
public class SuperClass
{
private int a;
public SuperClass ( int a )
{
this.a = a;
}
.
.
.
}
and our subclass is like this
public class SubClass extends SuperClass
{
public int b;
public SubClass ( int a, int b )
{
super( a );
this.b = b;
}
.
.
.
}
so here public SubClass ( int a, int b ) there is no problem even one of it's argument is private and belong to SuperClass??? if yes, how could it possible to access a private instance variable through another class???
When you call super(a);, you're not accessing the superclass from the subclass persay. You're calling the superclass's constructor, which in turn accesses it's own variable. It's completely valid, and makes logical sense.
Also, all variables and functions of the superclass are inherited by the subclass, such that the subclass is able to access the variables of the superclass. Note that you can't access it directly if it's private, but that doesn't mean that the subclass doesn't inherit the field.
Consider the following classes:
public class A {
private int a = 5;
public int getA() {
return a;
}
}
and
public class B extends A {
public int getnumber() {
return this.getA();
}
}
If I were to do this:
B x = new B();
then
System.out.println(x.a); //invalid
It would be invalid. You cannot directly access the a field inside the B object, but even if you can't see it, it still exists. We can validate that by doing this:
System.out.println(x.getnumber());
Which prints out 5.
public SubClass ( int a, int b ) {
super( a );
this.b = b;
}
int a is a new variable, different from private int a decalred in SuperClass. When you call super(a), you are passing the value inside of the parameter variable int a to the superclass's constructor. This is then stored in private int a
so here public SubClass ( int a, int b ) there is no problem even one
of it's argument is private and belong to SuperClass??? if yes, how
could it possible to access a private instance variable through
another class???
The scope of those parameters in that constructor is limited to that code block. int a, and int b are in no way related to class level variables, they just happen to be named the same.
You should probably make a public getter for the variable, but you could also simply declare the variable as "protected" (accessible to other classes in the same package, and by subclasses), or "public" - accessible by everything.
Related
I have a class with many subclasses,but when passing a subclass instance to some method which is supposed to receive an instance of the superclass, the attribute of the subclass is overwritten.
For example, the following code prints 0. What should I do to it so that it prints the subclass parameter value?
class A{
int cost;
}
class B extends A{
int cost = 10;
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.cost);
}
}
While fields can be shared within inheritance, given the right access modifiers (i.e. anything not private pretty much - default access will not work across different packages though), they are resolved at compile time, contrary to methods which are resolved at runtime (the latter is called virtual method invocation).
ints default to 0, and you're passing an A reference type, so A.cost's value of 0 is printed.
You have a range of options here:
Do not declare cost in B and assign cost value from A in B's constructor, or instance initializer, etc. to 10
An ugly, explicit cast in method4A, e.g. System.out.println(((B)a).cost);
Passing a B reference type instead of A in method4A
Keep both cost variables and declare a simple getter in A returning cost, and #Override it in B with the same implementation (it'll return B's cost even when invoked on a A reference if the instance actually is B)
Your problem doesn't have any relation with the overriding.
Declaring twice the same field in both classes (class and subclass) may be error-prone.
Do you really need to define two distinct fields ?
Why not reuse the field of the parent class in the subclass or provide a access to ?
Of course, in some specific cases, it is acceptable and desirable to define two distinct fields but for these cases generally you use the private modifier to isolate them.
A natural way to define such as behavior is providing a private field for cost and getter and setter in the parent class.
In this way, the subclass has way to value/set this field.
It could for example value the field from its constructor :
class A{
private int cost;
public void setCost(int cost){
this.cost = cost;
}
public int getCost(){
return cost;
}
}
class B extends A{
public B(){
this.setCost(10);
}
}
class Test{
public static void main(String[] args){
B b = new B();
method4A(b);
}
static void method4A(A a){
System.out.println(a.getCost());
}
}
You can use method overriding with getters like this:
class A {
int cost;
public int getCost() {
return cost;
}
}
class B extends A {
int cost = 10;
public int getCost() {
return cost;
}
}
class Test {
public static void main(String[] args) {
B b = new B();
method4A(b);
}
static void method4A(A a) {
System.out.println(a.getCost());
}
}
I'm new to java. Recently I saw some code which was similiar to this:
class A {
protected int myInt;
public static void main(String[] args) {
B b = new B();
b.myFunction();
}
}
class B extends A {
public void myFunction() {
this.myInt = 10;
}
}
As far as I know, when creating a subclass instance, an instance of its parent is created as well. All protected and public members of base class are accessible from the subclass.
If I override myInt there will be a difference between this.myInt to super.myInt because each class will have its own myInt (B will have access to both).
So, my question is: if I don't override myInt, which form is preferable, this.myInt or super.myInt?
You only need to use this or super when need to specify which scope are you using/referring to. In your case, I'll prefer to omit the this to simplify the readability.
super is used to represents the current instante of a parent class while this is used to represents the current class. You only need to used this or super if some variable or method overlaps (Have the same name) with one in a wide scope.
eg. If you have define a method parameter with the same name as class attribute, you need to use this to indicate that you are using the class attribute and not the method parameter.
public class A {
public int myInt = 1;
public static void main(String[] args) {
B b = new B();
b.myFunction(3);
}
}
class B extends A {
public int myInt = 2;
public void myFunction(int myInt){
System.out.println(myInt); // The parameter
System.out.println(this.myInt); // myInt from the current class (B)
System.out.println(super.myInt); // myInt from the parent class (A)
}
}
This example will print:
3
2
1
If you don't have this kind of collission, the use of this is optional:
public void myFunction2(){
System.out.println(myInt); // Both refers to the same
System.out.println(this.myInt); // variable myInt from class B
}
It's a matter of taste and the project's standards/guidelines more than anything else.
Personally, I wouldn't use either, and would just write myInt = 10.
Only one instance is created. If you instantiate a derived object, the parents constructor is called, but only one object is created. Also, the term this is more so used when there are different variables with the same name being referenced in a class.
For example a simple constructor:
class SupClass{
public int a = 1;
int incA(){
return ++a;
}
}
class MyClass extends SupClass {
public int a = 10;
public int b = 20;
MyClass() {};
MyClass(int a, int b){
this.a = a;
this.b = b;
}
int incA(){
return ++a;
}
public static void main(String args[])
{
SupClass d = new MyClass();
System.out.println(d.a); //1, members known of type SupClass at compile-time,
System.out.println(d.incA()); //11, methods are virtual, decided at run-time
}
}
Only use the super method when you want to explicitly use the value that is in the super class. To answer your question, only methods can be overwritten, member variables can not.
class A
{
int a = 2, b = 3;
public void display()
{
int c = a + b;
System.out.println(c);
}
}
class B extends A
{
int a = 5, b = 6;
}
class Tester
{
public static void main(String arr[])
{
A x = new A();
B y = new B();
x.display();
y.display();
}
}
Why does the output come out as 5,5? And not 5,11?.How would the y.display() method work?
why does the output comes 5,5?
Because A.display() only knows about the fields A.a and A.b. Those are the only fields that any code in A knows about. It looks like you expect the declarations in B to "override" the existing field declarations. They don't. They declare new fields which hide the existing fields. Variables don't behave virtually in the way that methods do - the concept of overriding a variable simply doesn't exist. From the JLS section 8.3:
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.
You can get the effect you want by changing B so that its constructor changes the values of the existing fields that it inherits from A instead:
class B extends A {
B() {
a = 5;
b = 6;
}
}
Note that these are not variable declarations. They're just assignments. Of course in most code (well, most code I've seen anyway) the fields in A would be private, so couldn't be accessed from B, but this is just example for the purpose of explaining the language behaviour.
In class A you declare fields a and b. The method display uses these fields. In class B you declare NEW fields of the same name. You're actually hiding the old fields not "overriding" them. To assign different values to the same fields use a constructor:
class A {
A(int a, int b) {
this.a = a;
this.b = b;
}
A() {
this(2, 3);
}
int a,b;
public void display() {
int c=a+b;
System.out.println(c);
}
}
class B extends A {
B() {
super(5, 6);
}
}
When doing this:
class B extends A
{
int a = 5, b = 6;
}
you are not redefining a and b, you're creating new variables with the same names. So you end up with four variables( A.a, A.b, B.a, B.b).
When you call display() and calculate the value of c, A.a and A.b will be used, not B.a and B.b
There isn's anything called variable overriding. That is why you are getting the same result in both the cases.
The reason is that Java uses the concept of lexical scope for variable resolution.
Fundamentally, there are two possible options to resolve free variables in a function ('free' means not local and not bound to function parameters):
1) against the environment in which the function is declared
2) against the environment in which the function is executed (called)
Java goes the first way, so free variables in methods are resolved [statically, during compilation] against their lexical scope (environment), which includes:
method parameters and local method variables
field declarations in the class containing method declaration
public field declarations in parent class
and so on, up the chain of inheritance
You would see this behaviour implemented in most programming languages, because it is transparent to developer and helps prevent errors with shadowing of variables.
This is opposite to the way methods work in Java:
class A {
public void foo() {
boo();
}
public void boo() {
System.out.println("A");
}
}
class B extends A {
#Override
public void boo() {
System.out.println("B");
}
}
class Main {
public static void main(String[] args) {
B b = new B();
b.foo(); // outputs "B"
}
}
This is called dynamic dispatch: method call is resolved dynamically in runtime against the actual object, on which it is called.
When you compile your code it pretty much becomes like:
class A extends java.lang.Object
{
int a=2,b=3;
public void display()
{
int c=a+b;
System.out.println(c);
}
}
class B extends A
{
int a = 5, b = 6;
public void display()
{
super(); //When you call y.display() then this statement executes.
}
}
class Tester
{
public static void main(String arr[])
{
A x = new A();
B y = new B();
x.display();
y.display();
}
}
And hence, when super calls, the method of class A is being called.
Now go to method of class A. Here int c = a + b; means
c = this.a + this.b; which is 2 + 3.
And the result is 5.
Class B declares variables in B scope, public void display() is part of A class and knows only about its own scope variables.
It's the inheritance functaionality which gives the output 5,5.
Java doesn't have anything like variable overriding. Thus, when the method display() is invoked, it accesses the variables inside the parent class 'A' and not the variables inside the subclass 'B'.
It can be explained with the same reason of why you can't print a variable declared in a subclass (and not in superclass) inside superclass method. The superclass method simply doesn't have access to the subclass variables.
However, you'll be able to print 5,11 if you have accessor methods to the fields in both the classes and you use those accessor methods to get the values instead of directly accessing using variable names. (even if the display() method is present only in superclass). This is because the overridden accessor methods are invoked (in second case) which return the values from the subclass.
Why does the output come out as 5,5? And not 5,11?
Whenever we have same instance variables (applicable to class variable as well) in a class hierarchy, the nearest declaration of the variable get the precedence. And in this case, nearest declaration of a and b from display () method is A’s. So class B’s instance variables go hidden. Hence in both cases, 5 gets printed.
How would the y.display() method work?
Another alternative is to have getter in both classes to get value of a and b.
class A
{
int a = 2, b = 3;
public int getA() {
return a;
}
public int getB() {
return b;
}
public void display()
{
int c = getA() + getB();
System.out.println(c);
}
}
class B extends A
{
int a = 5, b = 6;
public int getA() {
return a;
}
public int getB() {
return b;
}
}
class Tester
{
public static void main(String arr[])
{
A x = new A();
B y = new B();
x.display();
y.display();
}
}
Prints
5
11
I've seen answers for questions related to mine on Stack Overflow, but I am still left with some ambiguity. A parent class method has access to its own private instance variables. If a child class inherits the class, what happens when the getA() method is called on an instance of the Child class? Does it return the a from the Parent class or the a from the Child class?
class Parent {
private int a = 10;
public int getA() {
return a;
}
}
class Child extends Parent {
private int a = 22;
}
public class Test {
public static void main(String []args) throws Exception {
Child c = new Child();
System.out.println(c.getA());
}
}
As the Method getA() is inherited, if you call this Method, you'll always invoke the Parent's Method.
The current Object will be treated as a Parent and not as a Child, and the Parent's a will be returned.
Even though you have your own variable a, this variable wont override the Parent's a. They are different from each other, have different addresses and different values.
If you want getA() to return Child's a, you need to override the Method to return your new variable.
class Child extends Parent {
private int a = 22;
#Override
public int getA(){
return a;
}
}
You could also "go crazy" and do stuff like the following:
class Child extends Parent {
private int a = 22;
#Override
public int getA(){
int superA = super.getA();
return a+superA;
}
}
That way you could return the sum of Parent's and Child's a.
(Just an example)
This is a duplicate of this SO post.
The variable a in subclass Child hides the a in the parent class Parent.
Private variables are local to the class and in your code you are inheriting the properties of the parent class so you can access getA() and it will return the parent's attribute.
And you cannot access child's variable unless you have public getter method for child attribute.
Stick to basics "private member variable will only be accessed within the class by its own member functions and fields cannot be inherited" so basically when you are accessing the private variable A in parent class , the method is supposed to access its own private member rather then the private field of any child class.
Fields cannot be overridden.
In your code, an instance of child (like the one referred to by c) has two different fields, which are both called a.
You cannot access Parent's private variables inside Child, full stop. That's the entire point of private. There is nothing* you can write inside Child to make the parent's a field equal 22.
* Technically, you could with reflection. Reflection doesn't count though, since its purpose is essentially to allow you to break things, and do things that are otherwise impossible.
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.