This question already has answers here:
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 6 years ago.
class A
{
protected int i=10;
}
class B extends A
{
protected int i=15;
}
public class Test extends B
{
public static void main(String a[])
{
A obj=new Test();
System.out.print("i="+obj.i);
}
}
It's output is i=10, but how?
How is the memory allocation for the object will take place.
A obj=new Test();
Means, you are accessing the members of Class A and executing the methods of Test(polymorphism).
I suggest you to read the official docs on inheritance and polymorphism to understand deep.
Polymorphism is linked to objects not references. Since you are using a reference of type A, you will get A.i if you have method getI() in A and override it in B, then call obj.getI(), then you will get B.i's value
In java, Variable Overriding is not there. We have the concept of method Overriding.
In your code
A obj=new Test();
You can able to access members of A. If you have overridden same method in both the classes (Parent and Child). And you are calling that method with obj. This time you will get output from Child class overridden method. this is the concept of Polymorphism.
Line 1: A a = new A();
the method existence will be checked in A class and the method will be called from A class also.
a.g();//A class method will be called
System.out.print("i="+a.i);//A class i will be accessed
Line 2: A b = new B();
the method existence will be checked in A class and the method will be called from B class.
b.g();//B class method will be called and it will also check that it is` available in A also or not if not then compile time error.
System.out.print("i="+b.i);//A class i will be accessed
Related
This question already has answers here:
Does polymorphism apply on class attributes in Java?
(8 answers)
Closed 5 years ago.
Case 1:
In the below example if i call a.i it is printing 10 as answer. But A a = new B(); isn"t this like object of b is getting created so value 20 should be printed instead of 10.
class A
{
int i = 10;
}
class B extends A
{
int i = 20;
}
public class MainClass
{
public static void main(String[] args)
{
A a = new B();
System.out.println(a.i);
}
}
Case 2:
Also if i create the same program as above using methods inside classes instead of printing variable values as in above case then result is different :
class A{
void test(){
System.out.println("hi");
}
}
class B extends A{
void test(){
System.out.println("hello");
}
}
public class Test {
public static void main(String[] args) {
A a=new B();
System.out.println(a.test);
}
Now in this case hi is printed instead of hello , so why is the behavior different when i try to print variable value and when using methods? Overiding happens between the methods only and not with variables?
Because what you have in the first example has nothing to do with polymorphism as fields read are not dynamically dispatched.
What you have however is a name shadowing, so i in the statement A.i refers to the field declared in A and B.i is invisible at this point.
In Java only methods can be overriden, not instance variables.
When you declare a field with the same name as an existing field in a superclass, the new field hides the existing field. The existing field from the superclass is still present in the subclass, and can even be used
Check these -
Java Tutorial - Hiding Fields
JLS Example - Hiding of instance fields
This question already has answers here:
Why is an instance variable of the superclass not overridden by a subclass?
(7 answers)
Closed 5 years ago.
I am new to java and was reading about dynamic dispatching. I tried its program but the output that I got was unexpected. So in the following code I made two classes one Parent and another Child and in the Child class I made object of Child class and refer it by the variable of type Parent class. When I used the that variable to print the value of i(int type instance variable of both class) I got the value of parent class but it should print value of i that is in the child class. Can anybody please clear this up?
`
class Parent
{
int i=10;
}
class Child extends Parent
{
int i=20;
public static void main(String ar[])
{
Parent obj= new Child();
System.out.println(obj.i);
}
}
`
Variables can't be overriden in Java, take a look at this other question:
why instance variable of super class is not overridden in sub class method
This question already has answers here:
java non-static method getBalance cannot be referenced from a static context
(4 answers)
Closed 5 years ago.
Compare the way I print the value of the members of this class, in the static method (main) v/s a non-static method (the print method). In the static method, I need to use an object of this class, whereas, in the non-static method, I can refer to the class members directly.
I understand that the scope of static is class-wide, and is not tied to an object. Could someone elaborate a bit further on why I need to use an object in the static method, and it's not needed in a non-static method.
public class TreeDriver {
Tree tree;
TreeNode p;
public TreeDriver() {
tree = new Tree();
p =null;
}
public static void main(String[] args) {
TreeDriver obj = new TreeDriver();
obj.print(obj.tree.root, obj.p);
}
public void print(TreeNode nodeA, TreeNode nodeB)
{
System.out.print(nodeA.val + ", " + nodeB.val);
System.out.print(tree.root.val + ", " + p.val);
}
}
The print method isn't a static method, so it can only be called on an instance of the TreeDriver class (i.e. it can't be called from the class directly, like TreeDriver.print(...))
From your perspective, there's no way around this really, as you're accessing the instance variables p and tree in your method.
I would add that it'd probably make more sense if you split out your driver methods (e.g. main(String[] args) away from your data model (i.e. the instance variables and the print method).
Static methods do not need an object instance to be called.
In your above example, another class could call your main function like so.
TreeDriver.main(args);
Notice that TreeDriver is not an instantiated object. Contrast this with how a different class would need to call print.
TreeDrvier newTreeDrvier = new TreeDriver();
newTreeDriver.print(nodeA, nodeB);
You need an instance of the TreeDriver object. Members are defined for an instance of the class, not for the class itself, unless the member itself is static, which in that case would make it a class variable.
By definition, you don't need an instance to call a static method. There's really nothing more to say about "why" than just "that's the definition of a static method."
A non-static method is associated with a specific instance. As an analogy, if I tell you to start the car, you go start a specific car - you can't just grab the key and turn it in mid-air and expect it to "work."
Code:
public class ClassTest {
public static void main(String args[]) {
test1 cc = new test2();
System.out.println(cc.A);
System.out.println(cc.B);
cc.method1();
cc.method2();
}
}
class test1 {
static int A = 2;
int B = 5;
void method1() {
System.out.println("Inside method 1 test1");
}
static void method2() {
System.out.println("Inside method2 test1");
}
}
class test2 extends test1 {
static int A = 4;
int B = 6;
void method1() {
System.out.println("Inside method 1 test2");
}
static void method2() {
System.out.println("Inside method 2 test2");
}
}
OUTPUT:
2
5
Inside method 1 test2
Inside method2 test1
Question:
Why are only the methods overridden, but the variables remain unchanged?
Does this behaviour have a name? (like "overriding" for methods)
Overriding a method means let the same method call execute another method body (in the child class).
For a variable "overriding" is unnecessary: you can overwrite the variable's value.
Declaring a variable in the child class with the same name hides the parent classes variable and introduces an additional field.
For methods to be overridable a special mechanism is needed so that the place in the code may call the method that the actual class of the object specifies. This as opposed to accessing a field.
What happened here was that you've used type1 reference to point to an instance of test2. You can do this because test2 is a type of test1 - this is called Polymorphism.
test2 is derived from test1, so when you create an object of type test2 you will basically have two objects created, test2 and test1 (which will not reside in the heap as an autonomous object).
The JVM will access the fields of the object from its reference (because Java is a statically typed language).
So, although, test2 hides both fields of test1, when trying to access them from the test1 reference Java goes automatically to test1.
That's about it regarding the fields.
When dealing with methods we have a more complicated issue. Methods are overridden, thus, when the method table is built, the methods of test2 override the methods of test1. But, static methods are not instance methods.
Thus, when trying to access the static method method2, of test2 from the reference of test1, you are "abusing" the code. What you should be doning is calling test1.method2() or, if you want to access the static method of test2 you should use test2.method2().
Hope I explained it well enough...
In Above example you are creating reference of base class that time it will take value A=2,B=5 and it will allocate memory also.so when override to derived class, base class variable hide the derived class variable values that's why it can not override in derived class.
In line: System.out.println(cc.A);
This is not the correct way for calling static member, you should always use class name, eg: System.out.println(test1.A);
As per the Java specifications, the instance variables are not overridden from a super class by a sub class when it is extended.
Whether the variable be static or nonstatic. Only methods can be overriden.
That's why the output of cc.A & cc.B is from test1 class
For Method Overriding:
The code cc.method1(); here overrriding takes place, the object type(i.e the instance of class) actually determines which method is selected at run time, by this object declaration of new test2() in this code: test1 cc = new test2();
The compiler first checks the method in test1 class and then it checks in method in text2 class, if all the signatures (arguments, return types etc) are same then it invokes the sub class method
since it is overriding the base class method, because actual object is of class test2.
For Static methods:
Static methods cannot be overridden because method overriding only occurs in the context of dynamic (i.e. runtime) lookup of methods.
Static methods (by their name) are looked up statically (i.e. at compile-time).
thats why the output is from class test1.
For "static methods" in Java the exact method to call is determined at compile time.
You explicitly specify the name of the class whose static method you want to execute
say, I have the following code (it's a quiz question, so I can run it in my IDE but the logic how it's working is not quite clear to me):
public class Test {
public static void main(String[] args){
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
}
}
class A {
public static void doSth(){
System.out.println("Doing something in A");
}
}
class B extends A {
public static void doSth(){
System.out.println("Doing something in B");
}
}
class C extends B {
public static void doSth(){
System.out.println("Doing something in C");
}
}
The output will be the following:
Doing something in A
Doing something in A
Doing something in A
Thus, my first question is: what is the meaning of the declaration like
A aInstance2 = new B();
i.e., why to create an object of class B declaring it as an instance of class A? How the properties of aInstance2 as an object of class B change compared to the declaration
B aInstance2 = new B();
?
If I remove the word static from the declaration of the methods doSth() in the classes A, B, and C, the output changes to
Doing something in A
Doing something in B
Doing something in C
Thus, when the methods were static, the method doSth() of class A didn't get overridden by those of the subclasses and the output was always "Doing something in A" produced by the objects of different classes, whereas when it became an instance (non-static) method, it gets overridden (if I'm using the right term here). Why is it so?
Removing the word static you are doing Dynamic Binding , because you are pretty much saying : "Even though i know this object is of type A i want it to behave like a B ".
Adding the word static means you are making that method part of the class[Reference type] ,and each time you are calling :"A dosmth()" he knows it only applies to A so it shows the result of the mothod from the class A.
As to what would you do this?I for one learned about this feature from school and studied it even more when i decided to go to interviews becuase it;s one of the things that the interviewer wants to see if you can handle.
If you don't mind I will post a link with information about Static and Dynamic Binding
http://javarevisited.blogspot.ro/2012/03/what-is-static-and-dynamic-binding-in.html
Because static method is based on Reference type .
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
So internally it converts into :
A.doSth();
A.doSth();
A.doSth();
Static methods are class methods while non-static ones are instance methods. Therefore, when you call a static method over an instance you are actually calling it over the declared type of this instance. So, all below calls actually performs the same call: A.doSth() since all instances are declared as type A.
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
When you remove the static keyword, doSth() method becomes an instance method. Instance methods are performed over objects instead of classes. Moreover, when you re-declare an instance method in a subclass, this method is overriden by the subclass. In your example, class B and C override doSth(). Thus, each class provides its own implementation.
Overriding depends on having an instance of a class. A static method is not associated with any instance of a class so the concept is not applicable.
Making static methods works faster, because there's no need to wait until run-time to figure out which method to call.
Overriding in Java simply means that the particular method would be called based on the run time type of the object and not on the compile time type of it.
Illustration -
When doSth() is static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at compile time that without instance it should be called for A. No overriding.
When doSth() is not static:
A aInstance1 = new A();
A aInstance2 = new B();
A aInstance3 = new C();
aInstance1.doSth();
aInstance2.doSth();
aInstance3.doSth();
In the above code, the compiler will decide at run time that the method is not static and should be overridden by there respective instances.
static methods are at class level and act on the reference type(LHS of ==) unlike instance level methods which are dynamically dispatched based on the instance type(RHS of ==)