Java inheritance overriding instance variable
Java instance variables cannot be overridden in a subclass. Java inheritance doesn't work that way.
In your example, there is no method hiding (or overriding or overloading) going on.
There is hiding of instance variables though. In class
child
, the declaration ofa
hides the declaration ofa
inparent
, and all references toa
in thechild
class refer to thechild.a
not theparent.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
Trying to Get Svn2Git Working on Windows
Append Row to CSV File Ruby 1.9 CSV Lib
Get Available Diskspace in Ruby
Ruby - Open File, Find and Replace Multiple Lines
How to Download a File Over Http Using Ruby
Prawnto Displaying Tables That Don't Break When New Page
What Do I Need to Do to Get Hash.From_Xml() to Work
How to Increment an Integer in Ruby
Get Time from Datetime Variable in Ruby
Ruby on Rails Looks for CSS in Assets Instead of Public/Stylesheets
Sorting an Array of Arrays in Ruby
Error When Installing Ruby 2.1.3 with Rvm
Ruby Time.Parse Gives Me Out of Range Error
Convert Named Matches in Matchdata to Hash