Inheritance issue : Results are different on creating same class object [duplicate] - java

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

Related

Does parent class method use hidden variables [duplicate]

This question already has answers here:
Hiding Fields in Java Inheritance
(2 answers)
Closed 1 year ago.
This post was edited and submitted for review 1 year ago and failed to reopen the post:
Original close reason(s) were not resolved
I have a parent class A which has a primitive type property x
public class A {
String type = "A";
int x = 5 ;
void increment()
{
x++ ;
System.out.println(x);
}
}
I have a child class B which extends from class A, This child class also has propery x of String type
public class B extends A {
String type = "B" ;
String x = "Hello";
}
Now, both parent and child class has instance variable x with different type( int and String).
Parent class A has a method to increase value of X and now the method is available in the child class B ( Class B extends Class A, so all the methods in class A are accessible in class B)
Now I have a main method in a Runner class,
public class Runnable {
public static void main(String[] args)
{
//Creating object
B instanceOfB = new B() ;
//Invoke increment method
instanceOfB.increment();
}
}
While running the main method, I got an OUTPUT : 6
I am invoking increment method using reference variable instanceOfB
instanceOfB.increment();
instanceOfB is an instance of Class B.
By invoking this function, we are trying to increase the value stored in variable x, but x has reference to a String Object.
It should either throws compile time reception or run time exception because we are trying to increase a String object, It is not possible but I got output 6.
The behavior of instance variables and instance methods in a class hierarchy is different. If you wanted to access the value in the subclass from the superclass, you would need to wrap the subclass value with an instance method that is declared in the superclass but overridden in the subclass.

Why local variable can not be changed in inner class?

I will show you two code bunchs.
public class A {
int globalVariable;
public void foo() {
globalVariable++;
class B {
void foo() {
System.out.println(globalVariable);
}
}
B b = new B();
b.foo();
}
public static void main(String[] args) {
A a = new A();
a.foo();
}
}
here i declared one global variable, changed its value, declared one inner class and created instance of this class.This code will work well and print
1
Now check out this code:
public class A {
public void foo() {
int localVariable;
localVariable++;
class B {
void foo() {
System.out.println(localVariable);
}
}
B b = new B();
b.foo();
}
public static void main(String[] args) {
A a = new A();
a.foo();
}
}
i did all steps on first code except here variable is not global but local.Here i get an exception that says localVariable must be final or effectively final.I googled and understood that this is why value gets captured and passed to class.When we changed it class doesn't know about this changes and it cause confusing.
i have 2 questions:
1.if it cause some confusing and we have to not change it after declaration
why we don't get this exception on global variable
2.it it is about local variable value changes so we have to get this exception only if we change this value after class instance declaration.Isn't it?
1) I think your first question is answered by Why a non-final "local" variable cannot be used inside an inner class, and instead a non-final field of the enclosing class can?. (The question was earlier marked as a duplicate of that one.) Note that in general, the rule about not being allowed to modify variables doesn't apply to instance fields, or array elements, that are part of an object referenced by those variables. Therefore, this is legal:
public void foo() {
int[] localVariable = new int[1];
localVariable[0]++;
class B {
void foo() {
System.out.println(localVariable[0]);
}
}
B b = new B();
b.foo();
}
2) Your second code snippet can't succeed anyway, because you're incrementing localVariable before you've assigned a value to it, and that breaks the rules about "definite assignment". As for why Java doesn't let you use a variable that isn't modified after the inner class is declared: I don't know for sure. However, in Java 7 and earlier, the rule was that a local variable (or parameter) had to be declared final in order for it to be used in an inner class. In Java 8, this was relaxed--you didn't have to declare a variable or parameter final, as long as it was effectively final. However, I think the rule is that to be effectively final, the compiler determines whether the variable or parameter could have been declared final. And in this case, it can't, because this is illegal:
public void foo() {
final int localVariable = 3;
localVariable++;
}
In theory, the Java designers could have added rules to make the compiler determine whether a variable could be modified after a certain point. But that would have been more complicated, and it wouldn't have gained much, since you can still say
public void foo() {
int localVariable = 3;
localVariable++;
final int finalLocalVariable = localVariable;
class B {
void foo() {
System.out.println(finalLocalVariable);
}
}
}
Declaring a final variable to hold a copy of some other variable is a fairly common idiom when using inner classes, at least from what I've seen.

What does it mean if a static inner class is also final? [duplicate]

This question already has answers here:
What is the point of "final class" in Java?
(24 answers)
Closed 7 years ago.
public class ClassWithInnerClass {
int a = 10;
public static void outer(){
System.out.println("In method of outer class");
}
final static class Inner{
int b = 20;
public void innermethod(){
System.out.println("In method of inner class");
System.out.println("Inner class variable b = "+b);
}
}
}
In the above code, i have an outer class and then there is a static nested class with the non-access specifier 'final'.Does this make this class similar to "Constant" variables?
No, it's not similar to constant variable. It means that you can't create a sub-class of this nested class (Inner). This is similar to using the final keyword in top level (i.e. not nested) classes.
final on classes mean that they cannot be extended. It's no different from having final on a class defined at the top level.
final on classes is not the same as final on variables. final has different meanings based on where you use it. In general it describes a sort of immutability:
On variables, it means that you cannot change its value once initialized.
On methods, it means that once defined, it cannot be overridden in a subclass.
On classes, it means that the class itself cannot be subclassed.

Why is the output of this program i=10? [duplicate]

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

Is "inherited" the correct term to explain static method of superclass can be accessed by subclass?

Clarification: this question is not about access modifier
Confirmed that B.m() and b.m() statements both works in the following code:
class A {
static void m() { //some code }
}
class B extends A {
}
class Example {
public static void main (String [] args) {
B.m(); // running A's m() static method
}
public void try() {
B b = new B();
b.m(); // running A's m() static method
}
}
My question is can we said "static method is inherited"?
if "inherited" is the correct term, if we add a method to B class we same signature of the static class:
class A {
static void m() { //some code }
}
class B extends A {
static void m() { //some code }
}
class Example {
public static void main (String [] args) {
B.m(); // running B's m() static method
}
public void try() {
B b = new B();
b.m(); // running B's m() static method
A a = new B();
a.m(); // running A's m() static method, no polymorphism
}
}
In this case, notice that we have no polymorphism, is it the correct term to said that "static method is inherited but not overridden, subclass static method hide superclass static method"?
Last doubt, for these 2 terms, "inherited" and "overriden", which one is directly tied to the term "polymorphism" ?
Yes, I think "inherit" is the correct term here, even if it's not as descriptive as it might be. From section 8.4.8 of the Java Language Specification:
A class C inherits from its direct superclass and direct superinterfaces all non-private methods (whether abstract or not) of the superclass and superinterfaces that are public, protected or declared with default access in the same package as C and are neither overridden (§8.4.8.1) nor hidden (§8.4.8.2) by a declaration in the class.
That doesn't specify instance methods, but there are specific restrictions on what is allowed to hide or override what, which wouldn't make sense if static methods were not inherited.
Really though, I would simply view static methods as "accessible without qualification" rather than anything else, given that they don't take part in polymorphism etc. I think it's worth being very clear about that - for example, one static method can hide an inherited one, but it can't override it.
In other words, while I think "inherit" is technically correct, I would try to avoid using it without any further explanation.
For your second question, I'd say that based on the above, overriding is tied to polymorphism, but inheriting isn't necessarily.
(I would also strongly advise you to avoid calling static methods "via" variables, and also to use the name of the class which declares the static method wherever you specify the name at all. I know that's not part of the question, but I thought I'd just add it anyway...)
I think trying to apply words like 'inherited' and 'overridden' to this sort of thing is not productive. It's misleading because it gives the impression there is something comparable of what goes on with virtual instance methods, and you point out there isn't.
(But as Jon Skeet points out, the Java language spec doesn't agree with me, it groups these together in the same section.)
Guys I would like to share my knowledge in java with all java lovers out there!
First of all let me tell you that static members are those members which can be accessed directly without creating an object of that particular class, when static members of a class is used in some other class then it should be used by specifying the class name .(dot) static member's name(e.g. A.i in the following example), and also if any subclass class is getting inherited from a super class which has static members and if both subclass and super class are in the same package then that static members can be accessed from the base class without even using the class name of the super class. Please go through the
Example:
package myProg;
class A
{
static int i = 10;
A()
{
System.out.println("Inside A()");
}
}
class B extends A
{
public static void main(String[] args)
{
System.out.println("i = " + i); //accessing 'i' form superclass without specifying class name
System.out.println("A.i = " + A.i); //again accessing 'i' with the class name .(dot) static member 'i'
/*
we can also use the super class' object in order to access the static member compiler
will not show any error but it is not the exact way of using static members. static members are created
so that it could be used without creating the class object. see below the usage of object to use the
static member i.
*/
A obj = new A(); //creating class A object and A() also gets called
obj.i = 20;
System.out.println("obj.i = " + obj.i);
}
}
/*
This program was to show the usage of static member. Now, lets discuss on the topic of static member inheritance.
SO GUYS I WOULD LIKE TO TELL YOU THAT STATIC MEMBERS ARE NOT INHERITED. This undermentioned program is
to show the inheritance of static members.
*/
class A
{
static int i = 10; //initially the value of i is 10
static int j = 20; //lets use one more static member int j, just to see the value of it through class A, and B
static
{
/*
This is static initialization block(SIB) of class A,
SIB gets executed first in the order of top to bottom only one time
when the class is loaded.
*/
System.out.println("A-SIB");
}
}
class B extends A
{
static
{
i = 12;//trying to modify the i's value to 12
System.out.println("B-SIB");
}
}
class D extends A
{
static int k = 15;
static
{
System.out.println("D-SIB");
}
}
class C
{
public static void main(String [] arhs)
{
System.out.println("D.k: " + D.k);
/*here we are trying to access the static member k from class D,
it will try to search this class and then that class
will be loaded first i.e. SIB of class D will be loaded and SOP
statement of class D will be printed first. When the class loading
is done then the compiler will search for the static int k in class
D and if found SOP statement will be executed with the value of k.
*/
/*
ONE GROUND RULE: as soon as the compiler see this statement the compiler will load
class D into the memory, loading of class into memory is nothing but
storing all the static members (i.e. static constant & SIBs) into the
memory.
*/
System.out.println("B.i: " + B.i);
/*Now, this is what we are talking about... we think that static int i's
value is there in class B and when we write B.i it compiles and executes
successfully BUT... there compiler is playing a major role at this statement...
Try to understand now... we know that class B is the subclass of class A
BUT when the compiler sees this statement it will first try to search
the static int i inside class B and it is not found there, then since it is
the subclass of A, the compiler will search in class A and it is found
there. NOW, WHEN STATIC INT I IS FOUND IN CLASS A THE COMPILER WILL CHANGE
THIS STATEMENT B.i TO A.i and the class B WILL NOT AT ALL BE LOADED INTO
THE MEMORY BECAUSE STATIC I IS ONLY PRESENT IN CLASS A. But in the previous
statement static int k is present inside class D so when we try to access k's value
the class D will be loaded into memory i.e. SIB will be executed and then
the SOP statement of the value of k. USING B.i IS NOT WRONG BUT COMPILER
ASSUMES THAT THE PROGRAMMER HAS MADE A MISTAKE AND IT REPLACES THE CLASS NAME
B.i TO A.i. Thus this show that static members are not inherited to the subclass.And
therefore the vaue of i will NOT BE CHANGE TO 12 AS YOU CAN SEE IN THE SIB OF
CLASS B, it will be 10 only..
*/
System.out.println("A.j: " + A.j);//this statement will be executed as it is, compiler will not make
System.out.println("A.i: " + A.i);//any modifications to these statements.
System.out.println("B.j: " + B.j);//again compiler will modify this statement from B.j to A.j
}
}
Guys if you still have any confusion mail me at this email-id:
pradeep_y2k#yahoo.co.in
Regards
Pradeep Kumar Tiwari
Ok static methods cannot be overridden but can be redefined in other words its called hiding
check this http://www.coderanch.com/how-to/java/OverridingVsHiding they explain pretty well

Categories

Resources