Welcome to the Treehouse Community
Want to collaborate on code errors? Have bugs you need feedback on? Looking for an extra set of eyes on your latest project? Get support with fellow developers, designers, and programmers of all backgrounds and skill levels here with the Treehouse Community! While you're at it, check out some resources Treehouse students have shared here.
Looking to learn something new?
Treehouse offers a seven day free trial for new students. Get access to thousands of hours of content and join thousands of Treehouse students and alumni in the community today.
Start your free trialBen Attenborough
Front End Web Development Techdegree Graduate 32,769 PointsConfused by type casting
I've been following the Java Data Structures to this point, but I'm really confused by type casting. I'm trying to understand what it is and why we need to use it. I know it is connected to inheritance whereby a child class inherits the features of the parent class, but I'm really befuddled by what type casting is for.
The transcript right at the start of the video is particularly confusing to me:
"Another thing that you should know about inheritance is that it allows you to use an instance anywhere, one of its superclasses is required."
Can't we just pass the treet object in without calling it's parent class?
"Now for example, if there was a method that took an object as a parameter, we could pass it our Treet class and because Treet is an object, everything would work out just fine, implicitly."
Um, okay...
"It's also possible to go the other way and have a parent class redefine its type or explicitly cast itself as a child."
Now this really confuses me. How can a parent class treat itself as a child class? And why not just use the child class seeing as the child inheirts everything from its parent anyway?
Sorry, this has just has really twisted my mind!
4 Answers
Dan Johnson
40,533 PointsThe major advantage of using parent classes or interfaces when you can over the child classes is it allows for methods to operate on objects without needing to know the details for every single one of the child classes when they're not relevant. For example let's say we need to print out all the elements in a collection. If we go with the child classes we'll end up with something like this:
public class Application {
public static void main(String[] args) {
Set<Integer> uniqueNumbers = new HashSet<>();
List<Character> letters = new ArrayList<>();
uniqueNumbers.add(1);
uniqueNumbers.add(2);
uniqueNumbers.add(3);
letters.add('a');
letters.add('b');
letters.add('c');
printCollection(uniqueNumbers);
printCollection(letters);
}
// Generics aren't actually required for this method but I used
// for clarity's sake.
public static <Type> void printCollection(Set<Type> set) {
System.out.printf("Here are the %d element(s):%n", set.size());
for(Type element: set)
System.out.println(element);
}
public static <Type> void printCollection(List<Type> list) {
System.out.printf("Here are the %d element(s):%n", list.size());
for(Type element: list)
System.out.println(element);
}
}
You'll notice that these functions do the exact same thing, they state the element count then iterate through a collection. No specific methods are required for each type, these are all features of a collection. Even if the iterator that they use behaves differently internally or the size is calculated differently between the List and the Set, it doesn't matter, you just want it to perform the same action:
public class Application {
public static void main(String[] args) {
Set<Integer> uniqueNumbers = new HashSet<>();
List<Character> letters = new ArrayList<>();
uniqueNumbers.add(1);
uniqueNumbers.add(2);
uniqueNumbers.add(3);
letters.add('a');
letters.add('b');
letters.add('c');
printCollection(uniqueNumbers);
printCollection(letters);
}
public static <Type> void printCollection(Collection<Type> collection) {
System.out.printf("Here are the %d element(s):%n", collection.size());
for(Type element : collection)
System.out.println(element);
}
}
As for casting from a parent class down to a child class, this only works if the object in memory actually is the child class in question.
This is fine:
Object myObject = new String("Actually a string");
String myString = (String)myObject;
System.out.println(myString.toLowerCase());
This will throw a ClassCastException at runtime (specifically at the line of the myString declaration):
Object myObject = new Object();
String myString = (String)myObject;
System.out.println(myString.toLowerCase());
This is used for when you do need the specific methods of the child classes but are working with the parent classes. It's best not to use too heavily as it can work against the reasons mentioned above.
Craig Dennis
Treehouse TeacherI think this might help. As you probably know, String
has a method named length
that allows you to see how many characters it contains. As we saw a String
is an Object
, so it is possible that we could pass a String
to a method that is accepting an Object
.
String example = "This is an example";
public int justSomeExampleToShowTypeCastingOff(Object obj) {
if (obj instanceof String) {
String str = (String) obj;
return str.length();
}
// Otherwise, I don't know how to figure out the length
return 0;
}
// Call the method even though it takes an Object, I will pass in a String
justSomeExampleToShowTypeCastingOff(example);
Now, what if we wanted to call length
on that Object
. Well, Object
doesn't have that method, so we can't call obj.length()
, we need to cast it to something that does. So let's check and see if it is a String, and then we can access that method.
That make sense? Hope that didn't make things more murky ;)
Ben Attenborough
Front End Web Development Techdegree Graduate 32,769 PointsOkay thanks for that. I think these things should become clearer as I continue to do the course!
alexmearns
1,537 PointsI understand that you can do what you've just done, but could method overloading be used in this instance?
public String getTitle (String str) { //logic to return length }
public String getTitle ( //default logic }
If we can, then why is casting better? If we can't, I assume it's because java can't distinguish between two objects when overloading?
Mridul Gupta
2,144 Pointssee this link http://www.cs.utexas.edu/~cannata/cs345/Class%20Notes/14%20Java%20Upcasting%20Downcasting.htm
it will make it quite clear.
Kevin Faust
15,353 PointsHey mridul,
thanks alot for that link as it was extremely helpful. i went from being absolutely completely lost to actually knowing whats sorta going on. do you know if there are more of those notes? do you know where i can find them? i checked that cs.utexas.edu site but i have no idea.
or do you know any places where i can find similar notes to those that are easy to understand for beginners. because too much of the stuff online is way beyond my capabilities and get me even more confused than i am
Wan Nor Adzahari Wan Tajuddin
2,438 PointsThat link is very helpful! Whoever wrote that is a genius! I am eternally grateful. Sometimes I wish that Treehouse thought us like the article did. The article explained everything in detail and giving us examples like Animals > Mammals > Cats/Dogs thing.
Mridul Gupta
2,144 PointsHey kevin,
I definitely understand your problem as I also encounter it when i am new to some topic. But what i do is just google the problem and go through some links, and find the one for me.
Check this website too, it may help :- http://beginnersbook.com/2013/05/java-interface/
If you have doubts in some particular topics in java i can help you out with them too. :)
Kevin Faust
15,353 PointsHey Mridul thanks for your reply !! ill definetely check that site out. it looks like a promising website :)