• Post Reply Bookmark Topic Watch Topic
  • New Topic

Inheritance of static fields  RSS feed

 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hey!

I need a consistent mental model for understanding inheritance.
Inheritance defines an IS-A relationship; so every object of a subclass IS an object of the corresponding superclass. Moreover, public and protected members of the superclass are inherited (provided that the two classes are not in the same package, otherwise package-private members are also inherited) to become members of the subclass.

So far so good, but when it comes to static members things get messy!
First, some say static members are not inherited, but they are inherited according to the Java language specification. And if they weren't, "protected static" would make no sense.
My mental model of inheritance implies that when a subclass inherits a static field from the superclass, a new copy is formed! I know this is not correct. I know there is one static field anyway. But that is making my model inconsistent.

The bottom line is, something is wrong with my understanding. I need a model/explanation that covers this detail about static inheritance.

Thanks in advance.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Does the JLS say that non‑private static members of the class are inherited by subclasses? Yes, it does. It says that members are inherited, unless they are private (or default access in different packages), as you said. Whoever told you otherwise must have been mistaken.
But remember that static members of the class are not part of the object, only members of the class. And constructors and initialisers don't count as members at all.

I do not think that new copies of members are formed at all. Because a subclass object IS‑A superclass object, it contains part which is formed from the superclass. That part contains all its members, directly (fields) or indirectly (methods) via the corresponding Class<?> object.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I imagine that whoever said that static members are not inherited was mistakenly thinking of polymorphism. Static methods cannot be overridden, and have no polymorphic behaviour.
 
Liutauras Vilda
Sheriff
Posts: 4917
334
BSD
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike. J. Thompson wrote:Static methods cannot be overridden, and have no polymorphic behaviour.

In addition what Mike said, same as "final" methods cannot be overriden, but it doesn't mean they cannot be inherited.
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think for static methods term used is 'hiding' not 'overriding'.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Yes, it is called hiding. We have an FAQ about that.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:First, some say static members are not inherited, but they are inherited according to the Java language specification. And if they weren't, "protected static" would make no sense.

Hmmm. Not quite sure about that.

To me, 'protected' is a visibility specification, not an inheritance one - and before I read this thread, I would have said that static members are not inherited. But I'd have been wrong because the JLS is always right (well maybe not; but certainly "righter" than me ).

Which begs the question: If I have a public static synchronized method in a superclass, and I call it from a subclass - which class does it synchronize on?
If it is indeed inherited, then I'd expect it to synchronize on the subclass, but I honestly don't know what it does.

TBH, it probably doesn't matter too much, but it's interesting to ponder these things...

Fun thread Ramsin. Thanks.

Winston
 
Tushar Goel
Ranch Hand
Posts: 934
4
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
If it is indeed inherited, then I'd expect it to synchronize on the subclas

This sounds interesting. I will do some test on it tonight and share the result.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:. . . the JLS is always right (well maybe not; but certainly "righter" than me ). . . .
The JLS is not some sort of magic incantation which says, “arrays are objects,” or “non‑private static members are inherited,” and, lo and behold, arrays are objects, or non‑private static members are inherited. It is an instruction book which means, whenever anybody creates a Java® implementation, it must implement arrays as objects and it must make non‑private static members inheritable.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Campbell Ritchie wrote:It is an instruction book which means, whenever anybody creates a Java® implementation, it must implement arrays as objects and it must make non‑private static members inheritable.

So: does it explain what inheritance means in Java? Ie, what is it about a protected static method that makes it "inherited" or inheritable?

As I said: before I read this thread I would have said that static members aren't inherited, because I think of "inheritance" as applying to objects, and very closely related to polymorphism - and the fact that something is visible doesn't necessarily mean that it's inherited. But clearly I'm wrong ... at least according to the JLS.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:So: does it explain what inheritance means in Java? Ie, what is it about a protected static method that makes it "inherited" or inheritable?

I should add that this page from the tutorials doesn't enlighten me much further.

Winston
 
Liutauras Vilda
Sheriff
Posts: 4917
334
BSD
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:I think of "inheritance" as applying to objects, and very closely related to polymorphism - and the fact that something is visible doesn't necessarily mean that it's inherited.

I'm thinking about inheritance the way simpler, if my Mom got brown eyes, I inherited from her brown eyes too. But Campbell always tells do not think that way.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Liutauras Vilda wrote:I'm thinking about inheritance the way simpler, if my Mom got brown eyes, I inherited from her brown eyes too. But Campbell always tells do not think that way.

And I'd say he's right. It's fine for a general analogy, but it breaks down if you rely on it too deeply.

But I think I've answered my own question (amazing what a good shower does for the brain cells ):
static methods in Java can be accessed via objects as well as by class name - something I've always found a bit weird. But it does mean (I think) that you can create a polymorphic static API ... though precisely why you'd want to I don't know.

Winston
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:. . . But it does mean (I think) that you can create a polymorphic static API ... though precisely why you'd want to I don't know.

Winston
There are examples in Bloch and Gafter (Java Puzzlers) of that very phenomenon … and why it causes so much confusion. You end up with static methods determined by the type the variable's declared type not its runtime type. Method calls on instance methods are polymorphic and they are determined dynamically at runtime. The opposite of dynamic is static, which is (possibly) why the static keyword was reused to mean something different from what it means in C/C++.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:. . . So: does it explain what inheritance means in Java? . . .
No, I don't think it does.
 
Sachin Tripathi
Ranch Hand
Posts: 368
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I am posting this to check my understanding about "statics" and inheritance

1-static variables belongs to class don't require any instances,if instances of that class do exist they all share the same copy of that static variable

2-static methods too don't require any instances. If class has only static methods,its better to make the constructor private

3-You can't have non static methods or non static variables without instances inside static methods.As static method don't know to which instance those variables belong

4-Inheritance is "when more specific class(es) has the members of common (more abstract) class"
By member I mean instance variables and methods

5-static methods can be redefined but can't be overrided in subclass

6-You can access static variables or methods by reference variable pointing to object, also
(This is legal but not good)

7-When you invoke a method by reference variable. (Dot)
Compiler still pays no attention towards the instance, it just uses the reference variable to identify the class

8-As static variables are shared by instances of same class in the similar way class(Super) getting extended and having static variable,
Now all the instances of Super class and subclass shares the same copy of the static variable


If I am wrong somewhere do correct me by quoting the portion of my post where I got wrong

And if I missed any point do include it at end
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Sachin Tripathi wrote:
1-static variables belongs to class don't require any instances,if instances of that class do exist they all share the same copy of that static variable


Yes, that is correct.

Sachin Tripathi wrote:
2-static methods too don't require any instances. If class has only static methods,its better to make the constructor private


That's correct too. There are some classes like that in the JDK, such as the Math class.

Sachin Tripathi wrote:
3-You can't have non static methods or non static variables without instances inside static methods.As static method don't know to which instance those variables belong


If you change the word 'have' to call/access then this is correct. A static method can only access non-static members via a reference to an instance of the class.

Sachin Tripathi wrote:
4-Inheritance is "when more specific class(es) has the members of common (more abstract) class"
By member I mean instance variables and methods


Yes, when members are inherited they become accessible through instances of the extending class (assuming they are visible to the calling code). Static members can be inherited to, in which case you can access them using the extending class name.

Sachin Tripathi wrote:
5-static methods can be redefined but can't be overrided in subclass


This is true (known as hiding, as mentioned above), unless the member is final. Final static members cannot be hidden in subclasses if they were inherited by the subclass.

Sachin Tripathi wrote:
6-You can access static variables or methods by reference variable pointing to object, also
(This is legal but not good)

You can, even if the reference is null. That is why the following code won't throw an Exception



Sachin Tripathi wrote:
7-When you invoke a method by reference variable. (Dot)
Compiler still pays no attention towards the instance, it just uses the reference variable to identify the class

Which is why my example above does not throw a NullPointerException

Sachin Tripathi wrote:
8-As static variables are shared by instances of same class in the similar way class(Super) getting extended and having static variable,
Now all the instances of Super class and subclass shares the same copy of the static variable

Yes, unless the subclass hides the superclass member.
 
Mike. J. Thompson
Bartender
Posts: 689
17
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:But I think I've answered my own question (amazing what a good shower does for the brain cells ):
static methods in Java can be accessed via objects as well as by class name - something I've always found a bit weird. But it does mean (I think) that you can create a polymorphic static API ... though precisely why you'd want to I don't know.

Winston


The static members are inherited in a fuller sense than that. Yes its true that they can be accessed from object references, but the following code is also legal:



So the class inherits the static member in the same way it would a non-static member. You can access it from the subclass as if it was a direct member of the subclass.
 
Sachin Tripathi
Ranch Hand
Posts: 368
3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Thanks mike,
It feels good to have all concepts correct
I am preparing for OCAJP so all these will prove as good notes
 
Ramsin Khoshaba
Ranch Hand
Posts: 65
7
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I know what inheritance is at a very high level, as an IS-A relationship; also at a very low level, as a collection of details dictating how inheritance works. But I can't see the whole picture. If you show me a long chain of inheritance then I easily become overpowered by the complexity. I need an intermediary level between the two levels I just mentioned.

I personally find the model that "members are inherited" troublesome and not helpful. Semantically it implies that inherited static members are copies (and they are not).

Is it right to think of inheritance in terms of accessibility? For example, a subclass inherits the access to the public members of its superclass; instead of saying that a subclass inherits the public members themselves.
 
Campbell Ritchie
Marshal
Posts: 56533
172
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Ramsin Khoshaba wrote:. . . Semantically it implies that inherited static members are copies (and they are not).
No, it doesn't. Legal inheritance isn't the same thing but if you inherit a work of art from your parents, you don't get a copy. The inherited members actually form part of the subclass' instance.
Is it right to think of inheritance in terms of accessibility? For example, a subclass inherits the access to the public members . . .
Afraid not.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Mike. J. Thompson wrote:So the class inherits the static member in the same way it would a non-static member. You can access it from the subclass as if it was a direct member of the subclass.

Ah, 'makes sense. Thanks Mike. But it still makes me wonder about my previous question: suppose that, instead of a field, it's a synchronized method - which object gets "locked" when I call it from a subclass? I think I know the answer (or at least the one that makes sense to me) but it'd be nice to have it confirmed.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7972
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Inheritance only determines where a method can be accessed from. The methods will still operate in the context they are supposed to, regardless of where they are called. For non-static methods, the context is polymorphic, for static ones, it's not. That means that if you call a synchronized static method from a sub-class of the class where the method is defined, it will acquire a lock on the original class.

You can test this with a busy loop in a synchronized static method, and then call a different synchronized static method that's defined on the sub-class, which when it terminates, also terminates the other thread. If you go into a dead-lock, the two threads lock on the same monitor (note that this shouldn't happen).
 
Stephan van Hulst
Saloon Keeper
Posts: 7972
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator

 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Inheritance only determines where a method can be accessed from.

??? That's visibility, surely. Inheritance - at least the way I've always understood it - only applies to objects or types that are hierarchically linked - ie, via extends or implements.

For non-static methods, the context is polymorphic, for static ones, it's not. That means that if you call a synchronized static method from a sub-class of the class where the method is defined, it will acquire a lock on the original class.

Which was my assumption. However, as we know, Java allows static methods to be accessed via an object reference, which to me says that if both a parent and child class define the same static method, the class that gets locked (and indeed the method that gets executed) is the compile-time type, not the runtime one. So my assumption is that if I call it from a subclass without qualification, then it will be the subclass that gets locked.
(a) because it's the 'closest' definition.
(b) because it's the implicit compile-time type of this.
However, suppose a polymorphically invoked instance method in such a hierarchy calls that static method - which one gets called then? That will surely determine which object/class gets locked.

Hope I've made my doubt clear. Maybe it wasn't earlier.

Winston
 
Stephan van Hulst
Saloon Keeper
Posts: 7972
143
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Winston Gutkowski wrote:However, as we know, Java allows static methods to be accessed via an object reference

Which, as we hopefully all know, was a huge mistake :P

[...] if both a parent and child class define the same static method, the class that gets locked (and indeed the method that gets executed) is the compile-time type, not the runtime one. So my assumption is that if I call it from a subclass without qualification, then it will be the subclass that gets locked.
(a) because it's the 'closest' definition.
(b) because it's the implicit compile-time type of this.

I agree with what you're saying, but I prefer to use the terms formal type (the type of a variable) and actual type (the type of the object at runtime). I'm being pedantic, I know, but it may make a difference for future discussions.
Note that for (a), it's not because it's closest in definition, but because the super-type definition is being hidden.

However, suppose a polymorphically invoked instance method in such a hierarchy calls that static method - which one gets called then? That will surely determine which object/class gets locked.

Yes. That's why it's a bad idea to make unqualified calls to static methods. It's also a bad idea to hide static methods. You can prevent hiding by declaring your static methods as final.
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:Which, as we hopefully all know, was a huge mistake :P

I agree in general; but I do remember being shown a case where it made a lot of sense.

Trouble is: I can't for the life of me remember what it was. Bloody Alzheimers...

I do remember that it was moderately obscure, but something that I'd actually wanted (or done) before. If I remember what it was, I'll be sure to post it.

Winston
 
Winston Gutkowski
Bartender
Posts: 10575
66
Eclipse IDE Hibernate Ubuntu
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Stephan van Hulst wrote:I agree with what you're saying, but I prefer to use the terms formal type (the type of a variable) and actual type (the type of the object at runtime). I'm being pedantic, I know, but it may make a difference for future discussions.

No, you're quite right; and I'll try to remember the "official" terms.

Winston
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!