Instance Variables Inheritance

Java inheritance overriding instance variable

  1. Java instance variables cannot be overridden in a subclass. Java inheritance doesn't work that way.

  2. In your example, there is no method hiding (or overriding or overloading) going on.

  3. There is hiding of instance variables though. In class child, the declaration of a hides the declaration of a in parent, and all references to a in the child class refer to the child.a not the parent.a.

To illustrate this more plainly, try running this:

public static void main(String args[]) throws IOException {
child c1 = new child();
parent p1 = c1;

System.out.println("p1.a is " + p1.a);
System.out.println("c1.a is " + c1.a);
System.out.println("p1 == c1 is " + (p1 == c1));
}

It should output:

    p1.a is 10
c1.a is 11
p1 == c1 is true

This demonstrates that there is one object with two distinct fields called a ... and you can get hold of both of their values, if the access permits it.


Finally, you should learn to follow the standard Java identifier conventions. A class name should ALWAYS start with a capital letter.

Inheritance instance variables with Java

There were two decisions the creators of Java took that guided how they designed Java. One was that performance was a priority, it must not be judged unusable due to being too slow. The other decision was that they would target C and C++ developers, and make Java similar to what they were used to in order to make adoption easier.

So Java got public, private, and protected access like C++. Where package-private came in and why it is the default is not clear. They might have assumed developers would want to access variables directly in order to save on method call overhead. A long time ago I was working on a project with professional services people from Marimba, and we had the opportunity to investigate some of the implementation code, which was written with a lot of package-private members. When I asked why the explanation was it was for performance. This was before optimizations like JIT, so there may have been a concern that using accessor methods to get to frequently used superclass members might be too slow. On the other hand it might have been a style preference or they were using a freer approach as part of an evolving design, and maybe the idea behind making package-private the default was that this kind of freedom should be expected. (It's not something that has caught on judging by any other code I've read.) It was code written by Jonathon Payne and Arthur Van Hoff, so the professional service people may not have been in on the real reasons.

There's an interview where James Gosling talks about his reasons:

... one of the things that I had wanted to do early on was formalize setting and getting something in the language. You know how in JavaBeans there's this sort of convention that you write setter and getter methods? But I did a bunch of surveys of developers at the time, about whether or not they would like this to be there. And the average person went, "Oh my God!"

And so I didn't do it. But I think in retrospect, I should never have listened to them. I should have just done it. Because, I mean Beans basically layered on this facility that I had wanted to do anyway, but Beans did it as kind of an afterthought.

And because it's layered on as a naming convention, there's some things that don't fit together real well. And so, for instance, it would've made a lot of sense for the default protection for an instance variable to be private. And then the getters and setters, which the system would've known about at a much deeper level, to make them either public or package.

The direction in which the style has evolved has been to prefer making instance variables private, and expose them through getters if required. You can specify the private access modifier, like this:

private int humidity;

and then the variable won't be visible to the subclass.

Python : Multiple Inheritance : Why is instance variable of super's super class is not accessible?

Here is a little test for you that will help;

class A:
def __init__(self):
self.var1 = 5
print("In A")

class B(A):
def __init__(self):
self.var2 = 10
print("In B")

class C(B):
def __init__(self):
self.var3 = 20
print("In C")
super().__init__() ## Line 1

c = C()

will print;

In C
In B

but if you add a call in B to the constructor of A;

class A:
def __init__(self):
self.var1 = 5
print("In A")

class B(A):
def __init__(self):
self.var2 = 10
print("In B")
super().__init__()

class C(B):
def __init__(self):
self.var3 = 20
print("In C")
super().__init__() ## Line 1

c = C()

You get what you would expect;

In C
In B
In A

and this...

print(c.var1)
5

Instance Variables Inheritance

You are right, the book is wrong, or at least poorly worded


I would argue that the book is simply wrong, or at best, it's making a quite muddy explanation.

In all OO languages, the superclass and derived class don't have separate objects. When you create an instance of the derived class, it is also an instance of the superclass. There is one object and it is both classes at once.

Since there is only one object, there is only one set of instance variables.

This is the same as all other OO systems. The weird argument that book makes about how it just matters which method is run and how the methods themselves are what are really inherited does not add much in the way of clarity.

The problem with the terminology is that, sure, in a dynamically typed system there is no declaration in the first place, and so certainly the definition of the subclass doesn't inherit any field declarations ... because of course there aren't any. But just because there are no types to inherit doesn't make the opposite statement ("instance variables are not inherited") any more true, and it adds quite a bit of confusion because it implies that somehow the parent would have different instance variables, which is the nonsensical result of trying to talk about the objects the way they do.

Java Inheritance: How to override instance variables/fields from parent class?

Your parent class instance variables are Private to that, so you can't update them from Child class. So rather you use parameterize method or create Protected setter/getter for instance variables (or protected variable itself). In you your case the variables are final so you actually can't even update them. So technically that's not possible to use child class variables in parent class.

If you update your variable to protected and remove static/final modifiers (as you mentioned in comments that you can). Before calling method from parent class, update variable data before calling super method. You can do it as below:

Approach 1 : Updating data in parent class before calling parent class method.

Parent Class:

public class ParentClass {

protected String firstName = "Billy Ray";
protected String lastName = "Cyrus";
protected int age = 58;
protected String city = "Hunstville";

public boolean methodIWantToReuse() {
// Passing in the objects created above as argument, which have the Parent
// instance variable data
Object1 obj1 = new Object(firstName, lastName);

Object2 obj2 = new Object(age,city);

Object3 obj3 = new Object(obj1, obj2);

Object4 obj4 = new Object(obj3);
return someRandomMethodHere(obj4);;
}
}

Child Class:

public class ChildClass extends ParentClass {
protected String firstName = "Miley";
protected String lastName = "Cyrus";
protected int age = 27;
protected String city = "Los Angeles";

public boolean methodIWantToReuse() {
// Update data in Parent class first

super.firstName = firstName;
super.lastName = lastName;
super.age = age;
super.city = city;
return super.methodIWantToReuse();
}
}

Approach 2 : If you want to use parameterized method to make it stateless, you can do it as below:

Parent Class:

public class ParentClass {

protected String firstName = "Billy Ray";
protected String lastName = "Cyrus";
protected int age = 58;
protected String city = "Hunstville";

public boolean methodIWantToReuse() {

return methodIWantToReuse(this.firstName, this.lastName, this.age, this.city);
}

public boolean methodIWantToReuse(String firstName, String lastName, int age, String city) {
// Passing in the objects created above as argument, which have the Parent
// instance variable data
Object1 obj1 = new Object(firstName, lastName);

Object2 obj2 = new Object(age,city);

Object3 obj3 = new Object(obj1, obj2);

Object4 obj4 = new Object(obj3);
return someRandomMethodHere(obj4);;
}
}

Child Class:

public class ChildClass extends ParentClass {
protected String firstName = "Miley";
protected String lastName = "Cyrus";
protected int age = 27;
protected String city = "Los Angeles";

public boolean methodIWantToReuse() {
// Update data in Parent class first
return super.methodIWantToReuse(this.firstName, this.lastName, this.age, this.city);
}
}

NOTE: It's not good practice to keep local variables name same as the class level variables. But kept it here same for just understanding.

Inheritance and instance variable in Ruby

B inherits initialize from A.

At object creation, initialize is invoked. So you get @x set to 2 even for objects of class B.

I think, the sentences you are quoting refer to this scenario:

class A
def initialize
@x = 42
end
end

class B < A
def initialize
@x = 23
end
end

h = B.new

Now, h has just one instance variable @x with value 23. It is not like there is one @x from B and one from A. You can see this here:

class A
def initialize
@x = 42
end

def set_x_from_a
@x = 12
end

def print_x_from_a
puts @x
end
end

class B < A
def initialize
@x = 23
end

def set_x_from_b
@x = 9
end

def print_x_from_b
puts @x
end
end

h = B.new
h.print_x_from_a # => 23
h.print_x_from_b # => 23
h.set_x_from_a
h.print_x_from_b # => 12
h.set_x_from_b
h.print_x_from_a # => 9

Ruby—subclasses using instance variables of the parent

One quick way to achieve your goal would be to use the little known SimpleDelegator class:

class A
attr_reader :var

def initialize(var)
@var = var
end
end

require 'delegate'

class B < SimpleDelegator
def test
puts var
end
end

a1 = A.new('one')
a2 = A.new('two')
b1 = B.new(a1)
b1 = B.new(a1)
b2 = B.new(a2)
b3 = B.new(a2)

b3.test
#=> 'two'
b2.test
#=> 'two'
b1.test
#=> 'one'

This blog article ("5 ways of forwarding your work to some other object in Ruby") might be of interest to you.

Can child classes inherit instance variables from their parent class in Python?

You should call __init__ from the parent class:

class Person(object):
def __init__(self, name, occupation):
self.name = name
self.occupation = occupation

class Teacher(Person):
def __init__(self, name, occupation, subject):
Person.__init__(self, name, occupation)
self.subject = subject


Related Topics



Leave a reply



Submit