• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Jeanne Boyarsky
  • Ron McLeod
  • Paul Clapham
  • Liutauras Vilda
Sheriffs:
  • paul wheaton
  • Rob Spoor
  • Devaka Cooray
Saloon Keepers:
  • Stephan van Hulst
  • Tim Holloway
  • Carey Brown
  • Frits Walraven
  • Tim Moores
Bartenders:
  • Mikalai Zaikin

ClassCastException

 
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I have a class JavaStudent which extends the class Person, and I save instances of it in an ArrayList, which works fine. Problem is, it is for some reason saved as a Person instead of a JavaStudent. Why is that? I create the JavaStudent like this

Does that mean that I acually create a Person instead? Because when I try to access the methods which are "new" in JavaStudent, I get a ClassCastException
 
Greenhorn
Posts: 17
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hi,
When you are calling super(Fn, Ln, DoB), essentially what you are doing is saying Person(Fn, Ln, DoB) so it creates a Person object. What you should do is in your Person class, create/define common methods for Person which could be inherited by the JavaStudent class and any others you may wish to add (e.g. JavaTeacher class extending Person). I hope this helps!
Phil
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
When I call super(Fn, Ln, DoB), it just sets First and last namn and date of birth, but if I leave the call to super out, I get a "cannot resolve symbol constructor Person" error. Should I maybe change the way the constructor of Person works? It looks like this now
 
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I suspect that your constructor has nothing to do with your problem.
When you create an object using the constructor it constructs an object of the correct type, the call to super is used to construct the parts of the object that are derived from the super type.
I'm guessing that you are probably adding Person objects to the collection.
If you post a little of the code where you add and remove objects from the collection this would probably help.
 
Ranch Hand
Posts: 1067
2
IntelliJ IDE Spring Java
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
You need to cast what you get back from collections, to the proper sub-class. (Does that make any sense?)
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
This is the Create method which is inherited, and it adds a person. Should I redefine it?

When I get it, I cast it to a JavaStudent, which is where I get the ClassCastException I think
 
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator


Person MyPerson = new Person(Fn, Ln, Pn);


Right. Well, this explicitly creates a Person object, so that's what you'll get. Subclassing Person won't change the behavior of this method.
If you want to be able to have different subclasses create different kinds of objects, here's one way to do it: change that one line in Create() to look like

then define a method like this in the Person class:

Create() will now call this to make a Person. Now, here's the fun part. In subclasses of person, override makePerson to return an instance of the subclass instead:

When called on a subclass object, Create will now create an instance of the subclass.
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ah, smart! Thank you!
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Hmm... It still doesn't work. If I check what class it is (via .getClass()), I still get class Person. My compiler told me that the new method couldn't be accessed from a static context, so I made it a static method just to try it out, does that make a difference?
[ October 30, 2003: Message edited by: Carl Pettersson ]
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Yes, it does. Static methods can't be overridden (you can define a new method in a subclass, but it won't act polymorphically -- i.e., a static Create() will only call the makePerson() defined in Person.) If you make all these methods static, then they won't work as advertised.
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
But why is the create method static then? It isn't defined as a static method...
/edit
Just to clarify: it was the makePerson method which was made static, not Create.
[ October 30, 2003: Message edited by: Carl Pettersson ]
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I thought you just said you made it into a static method?
"Can't be accessed in a static context" means that you're trying to call a non-static method from a static one (probably main().) You're trying to call Person.create() as if it were static. If it's non-static you have to call it "on" an object.
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The program works like this;
The main method really doesn't do much, it initializes another non-static method.
This one runs a while-loop which just prints a menu and then has a switch-statement to check what the user wants to do.
Then it runs the right method, these methods are defined within the class PersonUtils. This class also is the one which contains the ArrayList where I keep the Persons/JavaStudents.
I made PersonUtils a class because I needed these methods to be extendable, they will be used and extended over the course of this year's Java-course.
[ October 30, 2003: Message edited by: Carl Pettersson ]
 
Jeremy Thornton
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Sounds like you are calling Person.create() somewhere (i.e. a static call) when you should be calling
// Person.create() - nope!
Person aPerson = new Student(...);
aPerson.create();
If you are going to use the template method mentioned earlier (calling an abstract method that has been defined in a subclass from within another method) then the methods need to be non-static to allow them to be overriden.
If I were you, I'd simplify the methods a little (just print out some text) so that you can see that the subclasses method is being used properly.
Without wishing to make things more complicated for you, I would consider moving the logic that adds Person objects into a collection outside the Person class hierarchy.
Jeremy.
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The code for creating/adding the Person or Student object is outside the Person class entirly. I think I've understood why I am making a static call though, but not how I should solve it. After trying to use Ernest's way of creating a new Person, the Create method looks like this

If I do it this way, it says that MyPerson might not have been initiated, but if I change it to be Person.makePerson(Fn, Ln, Pn), then it is a static call, right? I don't really know how to solve this...
 
Jeremy Thornton
Ranch Hand
Posts: 91
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
What your trying to do seems a little odd.
The makePersion method seems like it should be a straightforward constructor. Rather than

You should be doing something like
Person myPerson = new Student(...);
The reason that your getting warnings is that you've created a person variable pointing to nothing (Person MyPerson ; ) and then tried to call a method on it.
Does this make sense?
Alternatively, if you are sure that you want to treat Person as a factory for creating subclasses you could do something like:

[ October 31, 2003: Message edited by: Jeremy Thornton ]
 
Carl Pettersson
Ranch Hand
Posts: 73
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
That works, but then I always create Persons, which means I will have to re-define Create() every time I want to create a new sort of PersonSubclass... Isn't there some nice way to do this? I've been beating my head against this problem for almost a week now, so probably the answer is right under my nose
 
Ernest Friedman-Hill
author and iconoclast
Posts: 24207
46
Mac OS X Eclipse IDE Chrome
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I could definitely tell you more, because what you're describing is a well-understood paradigm, but let's step back a little bit and try to get to the root of your problem first.
You've got a method in class Person which creates a bunch of instances of class Person.
You want to be able to subclass it and arrange things so that when you call this method from a subclass JavaStudent, it creates instance of JavaStudent instead.
Is that it?
If Create() is a static method, then it simply doesn't know which Class it was "called on", so just subclassing is not enough. There's no way to do this without telling the method what kind of object to create, by passing it a parameter, or by some other means. Simple as that.
If Create() is nonstatic, then it does know what class it's being called on, but then of course, you need an object of the right class to call it on, which is a problem.
So what we're talking about is called the "Factory Method design pattern." You can find material about it all over the Web. Have a look at the linked web page, find a few others for yourself, then come back and ask questions if you need it.
 
reply
    Bookmark Topic Watch Topic
  • New Topic