Win a copy of Kotlin in Action this week in the Kotlin forum!
  • Post Reply Bookmark Topic Watch Topic
  • New Topic

Superclass variable referencing subclass objects  RSS feed

 
S Kak
Greenhorn
Posts: 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Below is a code I wrote which did not run for obvious reasons. As I understand the process flow:

When I declared yourname below, Java created a reference variable. This reference variable is of type Person. Then I created an object of class Player and referenced yourname to this newly created object. At this point Java created space in memory for the object which has three fields (name, age and score). However, when I tried adding information to score, Java threw error "cannot find symbol". From a code point of view, I get it. yourname is of type Person which does not have score as a field so at compile time Java checks for score in class Person and does not find it and hence throws an error. So my question here is:

As yourname refers to an object which has all three fields, why does Java not allow adding information to score? Should the error not be thrown at Person yourname = new Player() line hence not allowing the programmer to create an object having fields more than the reference type in the first place?

Also when I print out System.out.println(yourname) alone, the output is Player@HashCode, which implies that yourname belongs to the class Player which has three fields.

 
Henry Wong
author
Sheriff
Posts: 23283
125
C++ Chrome Eclipse IDE Firefox Browser Java jQuery Linux VI Editor Windows
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
S Kak wrote:
As yourname refers to an object which has all three fields, why does Java not allow adding information to score? Should the error not be thrown at Person yourname = new Player() line hence not allowing the programmer to create an object having fields more than the reference type in the first place?


The compiler/JVM does allow you to access the score field, you just can't do it with a Person reference. Just cast the reference to a Player reference, or just cast and use it directly.

Henry
 
Campbell Ritchie
Marshal
Posts: 55734
163
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch

You should make the fields in both your classes private, and access them via methods. But, in the current code, you declare the variable as type Person. Now some Person objects have a score field and some don't. If you declare it as Person, you can do this:-... or this:--Now, when you get to line 5, you have an object which does not have a score field. What are you going to do? Are you going to allow that assignment because some Person objects do have a score field? And what will happen at runtime, an Exception or something?
You are notnow in the realms of “behaviour undefined”, and that is dangerous. How can you be sure your program will behave correctly? How can you even say what correct behaviour is?
The correct answer is that the program cannot run. And the best way to ensure that a program does not run is not to allow it to compile in the first place. A Player is a Person, so you would expect the assignment to a Player (line 3) to run correctly.

So, you would expect the compiler error when you try to access the score field.

[edit]Correct not to now.
 
Knute Snortum
Sheriff
Posts: 4073
112
Chrome Eclipse IDE Java Postgres Database VI Editor
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch!

If the comment means that maybe the compile should throw an error at that point, then I would disagree.  I write this all the time:

 
Carey Brown
Bartender
Posts: 2996
46
Eclipse IDE Firefox Browser Java MySQL Database VI Editor Windows
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
By using constructors that also initialize the fields, and a generic toString() method, you can achieve your goals without needing a cast. If this doesn't work for you you may need an "instanceof" operator and a cast.
 
Ganish Patil
Ranch Hand
Posts: 529
19
Chrome Eclipse IDE Hibernate Java jQuery MySQL Database Netbeans IDE Spring Tomcat Server
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Carey Brown wrote:
I kept pondering on that how is this printing correct output   instead of fullyqualifiedclassname@hashcode then got detail information in source code, It was really awesome. I never knew we could print in this manner also.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!