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 trialMatthew Francis
6,967 PointsType Casting clarificaiton
In
mFactTextView = (TextView) findViewById(R.id.factTextView); /*this returns a view, hence it needs to be upcasted*/
TextView extends View, so View is the parent of TextView
https://developer.android.com/reference/android/widget/TextView.html
So, isnt this downcasting? you are downcasting View to TextView, but by that logic it wouldnt work since you cannot downcast a parent.
Can soemone clarify what is actually happening in the code? what does the cast signify?"
2 Answers
Philip G
14,600 PointsHi Matthew,
Imagine you have an Animal and a Dog class which extends the latter.
class Animal
{
public String greeting = "Hi, I am an Animal";
}
class Dog extends Animal
{
public Dog() {
greeting = "Hi, I am a Dog";
}
}
If you cast a Dog to an animal, it's an upcast.
Dog dog1 = new Dog();
Animal animal1 = (Animal)dog1;
Downcasting works the same, but only if you already know, that the Animal you are casting is a dog.
//Works
Animal animal2 = new Dog();
Dog dog2 = (Dog) animal;
Otherwise, you'll get a ClassCastException:
//Throws a ClassCastException
Animal animal3 = new Animal();
Dog dog3 = (Dog) animal;
It's the same here with View and TextView. Although findViewById()
(always) returns a View, it's in fact a TextView, who is just waiting to be casted down.
I hope I clarified it a bit. If you are still confused about the difference, please do not hesitate to ask me again in the comments!
Best Regards, Philip
Source: StackOverflow
Adam Sawicki
15,967 Points TextView mFactTextView = (TextView) findViewById(R.id.factTextView); /*this returns a view, hence it needs to be upcasted*/
This code means that in variable mTextView type TextView, we want assign obect TextView that represents widget in layout. We can accomplish this by using method findViewById which returns object of type View which as you noticed is general class for all views. Since you know what specific type of object your view is , you can downcast type View to this type of object and everything will be fine, you will receive object of proper type.
Matthew Francis
6,967 PointsMatthew Francis
6,967 PointsAhhh, findViewById() automatically upcasts everything to view, correct?
Philip G
14,600 PointsPhilip G
14,600 PointsYeah, kind of. In fact it's a function with a return type of view, which just returns the text view. I think the compiler does the upcasting automatically. To stay at our example:
Matthew Francis
6,967 PointsMatthew Francis
6,967 PointsThanks! one more thing...
Why do you have to downcast it again and not leave it as a View to be able to set a property for it?
eg;
Why cant you do this:
findViewById(R.id.relativeView).setBackgroundColor(COLOR.RED);
Instead of
Philip G
14,600 PointsPhilip G
14,600 PointsThe View Class has no setBackgroundColor() method. Upcasting goes automatically while downcasting doesn't. The compiler doesn't know that the View is, in fact, a RelativeView. Example:
Matthew Francis
6,967 PointsMatthew Francis
6,967 PointsHmm, if you press ctrl + f and search for setBackGroundColor() in:
https://developer.android.com/reference/android/view/View.html
the setBackGroundColor() method is in the Views class(I think?), but by that logic you don't need to downcast it, getting the id itself is enough.
I'm pretty sure I am misunderstanding this, could you clear my thoughts?
Philip G
14,600 PointsPhilip G
14,600 PointsWell, my bad :) When I wrote the answer, I haven't really looked up if the View class in fact has a setBackgroundColor Method. At the moment, I don't have a Computer with Android Studio available(holidays :), so could you send me the whole Code you tried?
In theory, you are right, it should work.
However, it can be that this is a foible of Android. Maybe in some cases, findViewById returns some kind of view. Could you try if this code works?
((View)findViewById(R.id.relativeView)).setBackgroundColor(COLOR.RED);
I'm sorry, but up to now I have always casted the output of findViewById() to the corresponding type. But this is good that this question came up, as we both can learn from it :)
Best Regards, Philip
P.S.: Maybe I'm totally missing something, and Ben Deitch or Ben Jakuben can clear this up?