Is instance variable shared between super class and sub class in java - java

class A{
String foo="bar";
void m(){
}
}
class B extends A{
//String foo="xyz";
void m(){
foo="xyz";
System.out.println(foo);
System.out.println(super.foo);
}
}
public class Dell{
public static void main(String[] args)
{
A a=new B();
System.out.println(a.foo);
a.m();
}
}
Here is foo variable shared between super class (A) and sub class (B).When I called super.foo in m() method why doesnt it called A class foo variable value that is bar.It seems that foo is shared between both the classes.Bu how is this possible? When we declare A with foo variable then it has its own copy and now when we overirde it and changed foo value in child class then how it is reflected back in Super class? Kindly explain we concepts in well way

This is essentially what you need to understand about instance variable scope within super and subclasses.
http://www.xyzws.com/javafaq/what-is-variable-hiding-and-shadowing/15

Related

Object class inheritance

We know that class A extends Object class implicitly but if we instantiate Object class object with class A constructor and try to access print() method of class A it shows a compile time error while in other case where class B extends class A and Class A object instantiated with class B constructor and try to access print() method works fine.
class A{
public void print(){
System.out.println("A");
}
}
class B extends A{
public void print(){
System.out.println("B");
}
}
public class MyClass {
public static void main(String args[]) {
Object o = new A();
o.print(); // error
A a = new B();
a.print(); // print B
}
}
This line:
o.print(); // error
You know that o is actually of type A.
The compiler could know, but in Java, it does not know. The compiler only knows that there is some variable named o, of type Object.
Thus the compiler slaps your fingers for invoking a method on o that the declared type Object doesn't support!
Other languages are "smarter" about such things, but in Java, that is how things are.
You example with class B extends A isn't the same as the case of A extends Object. The difference is that in the first case the superclass (A) contains the print() method, in the second case the superclass (Object) doesn't contain the print(). If you remove the print() method from the A class, the second part won't work either:
class A{
}
class B extends A{
public void print(){
System.out.println("B");
}
}
public class MyClass {
public static void main(String args[]) {
Object o = new A();
//o.print(); // error
A a = new B();
a.print(); // error
}
}
Because Object class does not have print() method and the reference o is of type Object, the compiler will throw an error.
In case 2 : class A has print() method thats why no compilation error and at runtime it calls class B's print() method because we assigned class B's reference at runtime.

Access to a protected constructor in Java

If I have a class A and its subclass B.
package washington;
public class A{
protected A(){}
}
package washington;
public class B extends A{
public B(){super();} // it works
public static void main (String[] args){
A b = new A(); // it does work.
}
}
The class A has a protected constructor, but I cannot access the constructor in B. I think it is a rule, however, I cannot find a webpage describing this situation.. All that I saw mention protected can be accessed from subclass, same-package.... e.t.c.
package california;
public class A extends washington.A{
public static void main (String[] args){
new washington.A(); // it does not work.
}
}
I wonder if this is because I use IntelliJ IDEA 2017.3.4.. compiler is javac 9.0.4
It seems that the problem is that you have your classes in different packages. Java doc says:
If the access is by a simple class instance creation expression new C(...), or a qualified class instance creation expression E.new C(...), where E is a Primary expression, or a method reference expression C :: new, where C is a ClassType, then the access is not permitted. A protected constructor can be accessed by a class instance creation expression (that does not declare an anonymous class) or a method reference expression only from within the package in which it is defined.
class A{
protected A() {
System.out.println("hello from A");
}
}
class B extends A{
public B() {
super();
System.out.println("hello from B");
}
public static void main (String[] args){
A b1 = new B(); // you can either do this
B b2 = new B(); // or this
}
}
Try running the program and you will see the expected result printed on console.

Why this data member is not accesible during upcasting?

I have a super and a sub class here , I'm trying to learn upcasting.
class Demo1{
int x=10;
void show(){
System.out.println(this.x);
System.out.println(this.s);
}
}
and the Child class:
class Demo2 extends Demo1{
int ashish=200;
String s="Nana";
public static void main(String... args){
Demo1 d=new Demo2();
d.show();
}
}
Here, I'm trying to print String s. Why does it shows a compilation error that the variable doesn't exist?
By my knowledge, during upcasting .. the object instance created has all the data members of the child class and its reference is given to parent class variable, so why doesn't this referencing to the data members of Demo2?
class Demo1{
int x=10;
void show(){
System.out.println(this.x);
System.out.println(this.s);
}
}
Demo1 has to be able to exist as an independent unit. If you created an instance of Demo1, by itself, it would not have any s, so this would be nonsensical.
What you could do, similar to what you're trying to do, would be something like
abstract class Demo1{
int x=10;
abstract String s();
void show(){
System.out.println(this.x);
System.out.println(this.s());
}
}
class Demo2 extends Demo1 {
String s = "foo";
public String s() { return s; }
}
This makes it explicit that Demo1 has a "hole" -- an implementation detail subtypes need to fill in, to tell it how to get s.
The super class doesn't know anything about the members (fields and methods) of any subclass. So, using the s field in super class is not allowed, thus you get the compiler error.

Can an Interface variable be reinitialised?

interface abs{
int a=10;// by default final static
void callme();
}
class B implements abs{
int a =11;// reinitializing
void call()
{
System.out.println("No problem"+a);
}
public void callme()
{
System.out.println("Call me"+a);
}
}
class main{
public static void main(String args[]){
B m=new B();
m.call();
m.callme();
}
}
In Herbert Schildt book, I have read that the interface variables are default Final and static. Which implicitly means that it will act like a constant. but when I am assigning 11 in the variable a in my above mentioned code, it is not giving any error.
o/p
No problem11
Call me11
You're not re-initializing the variable, but you're hiding it.
In order to access abs's a member, you have to refer it with the interface name. Something like:
System.out.println("No problem" + abs.a);
Because you have declared variable again
int a =11;
so see the error you want
do this in your class
a=11;
in your case the a is an entire new variable belonging to class B
You are not modifying the value of abs.a when you initialize a in class B. The field B.a simply hides the inherited a from the interface. You can still get to abs.a from code in class B by using the fully qualified name abs.a.
No, You can't reinitialize Interface variable. The variable in your Implementation Class is not interface variable A, but B class' instance variable. If you want to access Interface variable you reference it as abs.A
What you are actually doing is hiding the variable in interface by declaring a variable with same name in class B. You can verify it by using this code:
public interface Abs {
int a=10;// by default final static
void callme();
default void printA() {
System.out.println("A in interface: " + a);
}
}
public class B implements Abs {
int a =11;// reinitializing
void call()
{
System.out.println("A in class: "+a);
}
public void callme()
{
printA();
}
}
Then we have:
public static void main(String[] args){
B m=new B();
m.call();
m.callme();
}
It prints:
A in class: 11
A in interface: 10

Why doesn't the compiler complain when I try to override a static method?

I know that we cannot override static methods in Java, but can someone explain the following code?
class A {
public static void a() {
System.out.println("A.a()");
}
}
class B extends A {
public static void a() {
System.out.println("B.a()");
}
}
How was I able to override method a() in class B?
You didn't override anything here. To see for yourself, Try putting #Override annotation before public static void a() in class B and Java will throw an error.
You just defined a function in class B called a(), which is distinct (no relation whatsoever) from the function a() in class A.
But Because B.a() has the same name as a function in the parent class, it hides A.a() [As pointed by Eng. Fouad]. At runtime, the compiler uses the actual class of the declared reference to determine which method to run. For example,
B b = new B();
b.a() //prints B.a()
A a = (A)b;
a.a() //print A.a(). Uses the declared reference's class to find the method.
You cannot override static methods in Java. Remember static methods and fields are associated with the class, not with the objects. (Although, in some languages like Smalltalk, this is possible).
I found some good answers here: Why doesn't Java allow overriding of static methods?
That's called hiding a method, as stated in the Java tutorial Overriding and Hiding Methods:
If a subclass defines a class method with the same signature as a
class method in the superclass, the method in the subclass hides the
one in the superclass.
static methods are not inherited so its B's separate copy of method
static are related to class not the state of Object
You didn't override the method a(), because static methods are not inherited. If you had put #Override, you would have seen an error.
A.java:10: error: method does not override or implement a method from a supertype
#Override
^
1 error
But that doesn't stop you from defining static methods with the same signature in both classes.
Also, the choice of method to call depends on the declared type of the variable.
B b = null;
b.a(); // (1) prints B.a()
A a = new B();
a.a(); // (2) prints a.a()
At (1), if the system cared about the identity of b, it would throw a NPE. and at (2), the value of a is ignored. Since a is declared as an A, A.a() is called.
Your method is not overridden method. you just try to put #Override annotation before your method in derived class. it will give you a compile time error. so java will not allow you to override static method.
While goblinjuice answer was accepted, I thought the example code could improved:
public class StaticTest {
public static void main(String[] args) {
A.print();
B.print();
System.out.println("-");
A a = new A();
B b = new B();
a.print();
b.print();
System.out.println("-");
A c = b;
c.print();
}
}
class A {
public static void print() {
System.out.println("A");
}
}
class B extends A {
public static void print() {
System.out.println("B");
}
}
Produces:
A
B
-
A
B
-
A
If B had overridden print() it would have write B on the final line.
Static methods will called by its Class name so we don't need to create class object we just cal it with class name so we can't override static
for example
class AClass{
public static void test(){
}
}
class BClass extends AClass{
public static void test(){}
}
class CClass extends BClass{
public static void main(String args[]){
AClass aclass=new AClass();
aclass.test(); // its wrong because static method is called
// by its class name it can't accept object
}
}
we just call it
AClass.test();
means static class can't be overridden
if it's overridden then how to cal it .
Static members belong to class not to any objects. Therefore static methods cannot be overriden. Also overiding happens at run time therefore compiler will not complain.
Howeve, you can add #Override annotation to method. This will flag compiler error.

Categories

Resources