I have a Doubt
when we initialize our instance variables in Instance initialization block(s) in case of inheritance do they override the value of variable?
For example
class A{
int x;
}
class B extends A{
int x = 10;
}
public class C{
public static void main(String[] args){
A K = new B();
System.out.println(K.x);
}
}
o/p : 0
However when i use initialization blocks
class A{
int x;
{x = 15;}
}
class B extends A{
{x=20;}
}
public class C{
public static void main(String[] args){
A K = new B();
System.out.println(K.x);
}
}
OUTPUT 20
Why its so? why my initialization block(s) are affecting instance variables ? Moreover , i know that blocks are called when we make object but still the variable at output should correspond to variable type i.e A K (K should give value corresponding to class A)
You can override methods only, not variables. This code isn't "overriding" instance variables.
The first example has a different variables named x defined for A and B, making the variable an A means you see the variable defined for A (see the link provided by paulk23). In the second there is only one instance variable x which is visible to the subclass, the instance initializer assigns a value to an existing variable.
In the first example, you have two declarations of x, and in the second you only have one. In the second example, try changing B to:
class B extends A {
int x;
{ x=20; }
}
and you'll see the same behaviour as the first example: B defines a new variable that has an independent value from the one in A.
Related
I want to build a method that when it is called in main, automatically increment the value of variable.If first value is 0 when its called increment it to 1 , when I call for second time from 1 to be incremented at 2 and so on.
Notes: The method is part of a class and it called via object in main.
you can use the static variables. Static variables are initialized only once, at the start of the execution. These variables will be initialized first, before the initialization of any instance variables.
Create a static variable whose value can be updated in a function.
let this be your class
class Student {
static int b; //initialized to zero only when class is loaded not for each object created.
public void update(){
//incrementing static variable b
b++;
}
public void showData(){
System.out.println("Value of b = "+b);
}
}
and this be your main class
public class Demo{
public static void main(String args[]){
Student s1 = new Student();
s1.update();
s1.showData();
Student s2 = new Student();
s2.update();
s1.showData();
}
}
output:
Value of b = 1
Value of b = 2
Well, you kinda left a lot up for interpretation here, assuming the "value of variable" is part of the object the code would be something like this:
public class MyClass {
public int myVariable = 0;
public MyClass() {}
public void incrementMyVariable() {
myVariable++;
}
}
How you would handle this depends on where the variable your referring to is located ie. main method, object variable, etc... Additionally, if the variable needs to be kept constant across all the objects created for the class you would need it to be static.
class A{
int a = 10;
}
class B extends A{
int a= 20;
}
public class C {
public static void main(String [] args){
A a = new B();
System.out.println(a.a);
}
}
output : 10
How it print value from base class based on above code.
B already inherits a from A. Doing int a = 20; again hides the a inherited from A. This means that an expression of the form x.a will only evaluate to 20 if the compile time of x is B.
To get your expected behaviour, you can reset a in the constructor of B:
class B {
// no need to redeclare "a" here!
public B() { a = 20; }
}
When you make a variable of the same name in a subclass like you have done here, its called hiding. The resulting subclass will now actually have both properties.
Please refer below image,
1.Can Some one illustrate how it works? Why it prints 1 instead of 2?
2.From the Oracle Official Java tutorial, the definition of this: Within an instance method or a constructor, this is a reference to the current object — the object whose method or constructor is being called. You can refer to any member of the current object from within an instance method or a constructor by using this.
// Base Class
class A {
public int m = 1;
public void view(){
// Print variable m
System.out.println(this.m);
//print the current class name
System.out.println(this.getClass());
}
}
// Subclass extends Base Class
public class B extends A{
// Define another variable m
public int m = 2;
public static void main(String[] args) {
B b = new B();
b.view();
}
}
Below is the debug of the view(){}:
My Question is:
You can see the current object is B, when we usethis, it represents the B, m = 1 in base class A, m = 2 in derived class B, then use the this.m, it should print 2, isn't it?
Variables are not polymorphic in Java; they do not override one another.
what is the difference in following two pieces of code:
class B{
B(){}
}
//1)
class A{
B b = new B();
}
//2)
class A{
B b;
{
b = new B();
}
}
what is the difference in initialization in these two ways ? Also if both the statement are in one single class , what would be their sequence of execution and why?
EDIT: Adding some more clarification:
class C{
//1)
int i = 5;
//initializers block
{
i =7;
}
}
What is the sequence of execution for both these two statements ? What is the final value of i ?
UPDATE FOR THE NEW CLEARER QUESTION:
It sees now that I should have added more text to my question. I
wanted to know what would be the sequence of execution in case both
these statements(1 and 2) are in one single class for the same
variable ?
You are interessted something like this:
private class Test {
public String field = new String("1");
{
field = new String("2");
}
}
At first the field get the value 1, after that the constructor will be called and the init block which was placed in the ctor at compile time will be executed so the value of field is "2".
See this example:
http://ideone.com/72uxES
See also this Question and answer:
Default constructor vs. inline field initialization
OLD VERSION
I think you mean something like this:
Object obj = new Object()
Or
Object obj;
{
obj = new Object();
}
The curly brackets define a scope in which the variable life time is given.
Say we have following example:
import java.util.*;
import java.lang.*;
import java.io.*;
class Ideone
{
private static void checkObject(Object obj) {
if (obj == null)
System.out.println("Object is null");
else
System.out.println("Object is not null");
}
public static void main (String[] args) throws java.lang.Exception
{
Object obj;
{
obj = new Object();
checkObject(obj);
}
checkObject(obj);
}
}
The Output is:
Object is not null
Object is not null
But if we change it to:
{
Object obj = new Object();
checkObject(obj);
}
checkObject(obj);
It will not even compile and give these error msg:
Main.java:22: error: cannot find symbol
checkObject(obj);
^
symbol: variable obj
location: class Ideone
1 error
The first declares a variable obj and initialize it inside the scope
because it was outside declared it can be used after the scope.
If it is declared and initialized only in the scope it can be used only inside the scope.
The lifetime is bound to the scope.
If you use the curly brackets to initialize class fields
you are able to use more than one statement to initialize them
but you can also simply create a final method and call the method to initialize the field.
Example for curly brackets and field initialization:
class A {
private String field;
{
StringBuilder builder = new StringBuilder("Text").append(value)
.append(" ")
.append(otherValue);
//make some computations
//append to builder
//add to field
field = builder.toString();
}
Hint:
The Java compiler copies initializer blocks into every constructor.
Therefore, this approach can be used to share a block of code between
multiple constructors.
See working example:
http://ideone.com/X42rQI
As you know that the constructor is called when we instantiate a class. Also all classes have top level Class as Object in JAVA. Now whenever we call the constructor of any class for your case A as new A() it leads us to call first super() leading to Object's constructor.
Now in your example1 your variable b is declared and initialised in the class itself. So before the constructor of class A is executed the variable b is initialised i.e. all the code that you write in public A() will be executed after b has been initialised.
In your example2 your variable b is declared in the class but is being initialised in the constructor of A. If you have some code before the line b = new B(); that code would be executed first then the b would be initialised.
See the example below :
Class A{
B b = new B();
public A(){
b == null; //FALSE as it has been already initialised.
}
}
But
Class A{
B b ;
public A(){
b == null; //TRUE as it has not been initialised.
b = new B();
b == null; //FALSE as it has been just initialised.
}
}
I assume it has to do with the following:
Initializing Instance Members
Normally, you would put code to initialize an instance variable in a
constructor. There are two alternatives to using a constructor to
initialize instance variables: initializer blocks and final methods.
Initializer blocks for instance variables look just like static
initializer blocks, but without the static keyword:
{
// whatever code is needed for initialization goes here
}
The Java compiler copies initializer blocks into every constructor.
Therefore, this approach can be used to share a block of code between
multiple constructors.
https://docs.oracle.com/javase/tutorial/java/javaOO/initial.html
Basically it means that all instance variables that are between the brackets will be initialized for all constructors. Even though your classes dont have multiple constructors
added example with multiple constructors
class A{
B b;
int index;
String result;
{
b = new B();
index = 0;
}
public A(int temp){
// nothing
}
public A(int temp, String test){
this.result = test;
}
public int getIndex(){
return index;
}
}
It doesnt matter here which constructor you use, as the initialization between the brackets is copied into both constructors. a.getIndex() will always return '0'
public class Foo {
public int a = 3;
public void addFive(){
a += 5; System.out.print("f ");
}
}
public class Bar extends Foo {
public int a = 8;
public void addFive(){
this.a += 5;
System.out.print("b " );
}
}
public class Test {
public static void main(String args[]){
Foo f = new Bar();
f.addFive();
System.out.println(f.a);
}
}
I am getting output b 3 .why it is not giving b13 as output.Can anyone please explain.
Assuming class Foo is declared as below
class Foo
{
public int a = 3;
public void addFive()
{
a += 5;
System.out.print("f ");
}
}
Variables have no concept of overriding. They are just masked.
It is printing 3 because, when you use a superclass reference to access a variable, it accesses the variable declared in superclass only. Remember that superclass doesn't know anything about subclass.
class Foo {
public void addFive() {
a += 5; System.out.print("f ");
}
}
you don't have 'a' variable defined, so this example doesn't even compile.
correct code:
class Foo {
public int a;
public void addFive() {
a += 5; System.out.print("f ");
}
}
and see link https://stackoverflow.com/a/2464254/1025312
I assume that you meant to declare an integer field a in class Foo.
The answer to your question has to do with concepts of 'overriding' and 'hiding', as others have pointed out. Another way to explain it is that for member variables, there is no such thing as 'dynamic dispatch'. What that means is that, if you access a member of a certain object, the system checks at run time which member you mean, by looking at the class hierarchy.
So, when calling the method f.addFive, at run time, the system will see that your object is actually a Bar and not a Foo, and so take the addFive function that you defined in the Bar class.
That does not happen for member variables: you access f.a in your print statement, and at compile time it is decided that right there you want to access the field a declared in class Foo there -- and so, that is what will happen at run time.
Now, the reason that there is no dynamic dispatch for member variable access is performance: it would be very expensive to go through the whole 'see what object this really is' logic every time you just want to add some value to a member variable.
Declaring public int a = 8 in Foo class instead of Bar class it should work... printing B 3.
But I suppose you are talking about a question included in the Java certification exam, so you have to correct the code of the Foo class adding public int a = 3.
You cannot override a variable in Java, but declaring in as public (or protected) in the super-class you can use it also in all inherited classes.
In this case the right output is B 13 because in the test class you are using a Bar object as a Foo object, so the value of a is 3 and not 8.