Why subclasses does not override the value of their superclass variable? - java

I have three classes as following, class b and c are extending class a. I am wondering why the code is not reading the value of b and c variables.
public class a{
protected int myvalue = 1;
}
public class b extends a{
private int myvalue = 2;
}
public class c extends a{
private int myvalue = 3;
}
body of my main method
ArrayList<a> myList= new ArrayList();
myList.add(new b());
myList.add(new c());
for(int i =0;i<myList.size();i++)
System.err.println("value is:" + myList.get(i).myvalue);
output
1
1
From Oracle website:
Within a class, a field that has the same name as a field in the
superclass hides the superclass's field, even if their types are
different. Within the subclass, the field in the superclass cannot be
referenced by its simple name. Instead, the field must be accessed
through super, which is covered in the next section. Generally
speaking, we don't recommend hiding fields as it makes code difficult
to read.

You are shadowing your field myvalue and not overriding it, I believe something like this will do what you want
public class a{
protected int myvalue = 1;
}
public class b extends a{
public b() {
myvalue = 2;
}
}
public class c extends a{
public c() {
myvalue = 3;
}
}
Also, please don't use Raw Types
// ArrayList<a> mylist = new ArrayList();
ArrayList<a> mylist = new ArrayList<>(); // <a> on Java 5 and 6

Related

Why does the object refers to the value of the parent class instead of the class it is assigned to?

Can someone explain why the output is 10 and not 20?
Why does the object refers to the value of the parent class instead of the class it is assigned to?
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);
}
}
The instance you're creating is of type A, so since both variables have the same name, you'll get the superclass' one, if you want B's you should do
B b = new B()
System.out.println(b.i)
You shouldn't use variables of the same name like that in between superclasses and subclasses, gets very confusing and kinda defeats the purpose of inheriting.
In Java, methods are overridden not variables. So variables belong to their owner classes. a is a reference of type A that point to an object of type B but remains of type A.
To call the i of B, you have to cast a to B.
A a = new B();
System.out.println(((B)a).i);
Can someone explain why the output is 10 and not 20?
Since the value of i is defined in the class A and is NOT overridden/re-assigned by the definition of class B as you might just be assuming. Adding a custom constructor could clarify your doubts further of what you might be intending to do:
class A {
int i = 10;
}
class B extends A {
public B() {
this.i = 20;
}
}
A a = new B();
System.out.println(a.i); // would now print 20
Declaring the same variable i in class B would have its own scope and does not inherit from the class A.
Variables can not be overridden in Java as they are resolved at compile-time; You can use super to set its values,
class A {
int i = 10;
}
class B extends A {
int i = 20;
public B() {
super();
super.i = i;
}
}
A a = new B();
System.out.println(a.i); //20

Creating an array of subclasses of a class

I'm trying to store all subclasses of A which are constructed by super() in the array child (in this case B). All the children are in the same package. This is my approach but I don't know how the class could store itself inside an array or pass itself as argument to super().
class A {
static int i = 0;
A[] child = new A[10]
int someval;
A(int val){
someval = val;
child[i] = ???;
i++;
}
}
class B extends A{
B(){
super(val);
}
}
Is this even Possible? With my approach B will only be added when a new B() is created? Is it possible to get a complete array without creating a new object?
public class A {
private static final List<A> instances = new ArrayList<>();
public A() {
instances.add(this);
}
public static List<A> getInstances() {
return instances;
}
}
Now A.getInstances() can be called whenever you like, and will contain instances of anything that extends A.

Java inheritance fields [duplicate]

This question already has answers here:
Is there a way to override class variables in Java?
(17 answers)
Overriding member variables in Java ( Variable Hiding)
(13 answers)
Closed 5 years ago.
I am not able to understand the following output.
I don't know why the output is 10, I think the line A a = new B() creates a new instance of class B, I think the result should be 20
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);
}
}
Why this works like this .. please explain.
First, see Hiding Fields (emphasis added)
Within a class, a field that has the same name as a field in the superclass hides the superclass's field, even if their types are different
In other words, this isn't "inheritance" since you're actually hiding A's i behind B's i, and you are using a reference object of A, so you are getting its fields. If you did B b = new B(), you would see 20, as expected.
If you expect true overrides, try using methods.
class A {
public int get() {
return 10;
}
}
class B extends A {
#Override
public int get() {
return 20;
}
}
See
A a = new B();
System.out.print(a.get()); // 20
If you really want to see both at once, see this example.
class A {
int i = 10;
}
class B extends A {
int i = 20;
#Override
public String toString() {
return String.format("super: %d; this: %d", super.i, this.i);
}
}
And
A a = new B();
System.out.print(a); // super: 10; this: 20
In java you cannot override an instance variable. The output you are getting is expected. In Java you can only override instance methods and not instance variables.
If you want 20 as an output you may use getter methods over those instance variables.
class A {
int i = 10;
int getI() {
return i;
}
}
class B extends A {
int i = 20;
int getI() {
return i;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.getI());
}
}
Polymorphism is not applicable for fields in Java.Evaluating Variables decision is taken at compile time so always base class variables are accessed.
Because you define 2 variables: one in the subclass B, and one with the same name in superclass A.
A a = new B();
a.i; // refers to A.i
If you cast the A to a B, it will access B.i:
System.out.println(((B)a).i);
I think you need to use 1 variable:
class A {
int i;
public A() {
i = 10;
}
}
class B extends A {
public B() {
i = 20;
}
}
public class MainClass {
public static void main(String[] args) {
A a = new B();
System.out.println(a.i); // will print 20
}
Member variable i is already defined in class A.
In order to achieve what you are looking for, change the class B as shown below:
class B extends A {
public B() {
i = 20;
}
}

Use of casting to interface type

interface I {
int element = 10;
}
class A implements I
{
int element = 2;
public static void main (String[] args) throws java.lang.Exception
{
A a = new A();
System.out.println(a.element);
I i = (I)a;
System.out.println(a.element + " " + i.element);
}
}
Output:
2
2 10
Even after I cast object of type A to I the value of element in I doesn't change.
If I is a class and A extends I then I can change the value of element in A and cast it to I such that i.element has modified value (in this case A does not have element member)
So does the concept of casting exist in such cases? (class object cast to interface type)
Even after I cast object of type A to I the value of element in I doesn't change.
I i = (I)a;
That line shows that the instance of a pointing to the type I. Which means, you are accessing the variables from type I and telling that execute the methods from class a.
Polymorphism strictly for methods. There is no polymorphism on variables.
Here is the example :
public interface TestInterface {
int testvarInterface = 0;
}
public class TestParent {
int testvarFromParent = 0;
}
public class TestClass extends TestParent implements TestInterface {
public static void main(String[] args) {
TestClass s = new TestClass();
System.out.println(s.testvarInterface);
TestInterface in = (TestInterface) s;
in.testvarInterface = 15; // ERROR: The final field
// TestInterface.testvar
// cannot be
// assigned
System.out.println(s.testvarFromParent); // Points to LHS
TestParent parent = (TestParent) s;
parent.testvarFromParent = 20;
System.out.println(parent.testvarFromParent);
}
}
After all you have to remember that the variables points to LHS (naive, bit still), where as in your interface case, since it is public and static final you cannot modify it.
You cannot overwrite the value of I.element in implementing classes because variables defined in interfaces are static final. Being static they are not instance variables. And being final they cannot be overwritten.
So A.element is hiding I.element when you are working with a reference of type A. But not when you cast the A instance to its interface type I.

How to use variables from one class in other classes?

How can I use variables from one class in my other classes? For example, I have
Class 1
public class maintype {
public int A = 1,
B = 2,
C = 3,
D = 4;
public String E, F, G
public static void main(String args[]) {
}
}
Class 2
public class subclass {
public numbers() {
AB = A + B;
}
}
I want to use the variable a and b in my second class but it is giving me an error. saying no such variable exist but I don't want to create that variable again in my second class.
you forgot to extend
public class subclass extends maintype{
public numbers(){
AB = A+B;
}
}
You can extend the class as in::
public class subclass extends maintype{
public numbers(){
AB = A+B;
}
}
This is the common feature of java Called Inheritance, Explained below::
Definitions: A class that is derived from another class is called a subclass (also a derived class, extended class, or child class). The class from which the subclass is derived is called a superclass (also a base class or a parent class).
Excepting Object, which has no superclass, every class has one and only one direct superclass (single inheritance). In the absence of any other explicit superclass, every class is implicitly a subclass of Object.
Classes can be derived from classes that are derived from classes that are derived from classes, and so on, and ultimately derived from the topmost class, Object. Such a class is said to be descended from all the classes in the inheritance chain stretching back to Object.
For more details follow this link::
http://docs.oracle.com/javase/tutorial/java/IandI/subclasses.html
You forgot the extends keyword in subclass, so I have corrected it for you.
Superclass:
public class superclass{
public static int A = 1;
public static int B = 2;
public static int C = 3;
public static int D = 4;
public String str1 = "E";
public String str2 = "F";
public String str3 = "G";
public static void main(String[] args){
//What do you want to put here?
}
}
Subclass:
public class subclass extends superclass {
public void numbers(){
int A = superclass.A;
int B = superclass.B;
int AB = A + B;
}
}

Categories