public class A {
public void m1() {
System.out.println("A m1");
}
}
public class B extends A {
public void m1() {
System.out.println("B m1");
}
public void m2() {
System.out.println("B m2");
}
}
public class Result {
public static void main(String[] args) {
// TODO Auto-generated method stub
/*A a = new A();
a.m1();
B b = new B();
b.m1();
b.m2();
*/
A ab = new B();
ab.m1();
}
}
In the above code, I have a Class A and Class B that extends Class A. In class C I am creating the object of class B and it's been assigned to class A. when I try to call ab.m1() it calling the method in class B.but when I try to call ab.m2() i get compile time error. I am not understanding why class B method is called during ab.m1(). can someone help me in understanding the concept much better.thanks in advance.
A ab = new B();
You create a reference of type A and point it to an object of type B. This is valid and legal because B extends A, so an object of type B IS-A type A. That's why, when you call ab.m1(); you're calling the method defined in B. Your object type is B, so it overrides the method defined in A.
However, you can't call ab.m2() because the reference is type A, and knows nothing about new methods defined in B that weren't included in A. The reference only has access to the things defined in A (and anything that it might inherit from its super types, like Object).
B -->A// B is-a A
A ab = new B()//object of B is created and reference variable is type of Super type as A is super class of B
since ab.m1() is type of A class and can be accessible through super variable.
ab.m2() is type of B class and can not be accessed using super type reference, thats where down casting comes into picture.
try:
B a = (B)ab;// down casting
a.m1();
a.m2();
now you call both method of B class.
Related
I decided to simulate this example code from Android app:
TextView txt = (TextView) findViewById(R.id.activity_display_message);
findViewById returns View object and then we cast it to a TextView one(TextView is a subclass of View)
It seems I have misunderstood how it works. I was expecting this code to work because C extends B and therefore I should downcast a B object to C.
But I am getting an exception at runtime that I can't cast B to C.
So can anyone explain where I am wrong? And why the Android sample works?
public class A{
public static void main(String[] args){
B b = new B();
b.f();
C c = (C)b;
}
}
class B{
public void f(){
System.out.println("Class B");
}
}
class C extends B{
public void f(){
System.out.println("Class C");
}
}
Cast operation lets you change the static type of your object, which is another way of saying "tell the compiler what you know about the type of the object being cast."
If you have a variable of type B which contains an object of type C, you are allowed to cast that variable to C:
B b = new C();
C c = (C)b; // works fine
This is allowed precisely because b's object is actually a C.
When the object referenced by b is not a C, the compiler will catch your mistake, and throw a cast exception:
B b = new B();
C c = (C)b; // throws class cast exception
The difference between a successful and unsuccessful is decided by the actual type of the object at runtime. The code that works manages to cast a View to TextView because the variable which is statically typed as View actually references a TextView at runtime.
In java, you cannot assign a superclass reference variable to a subclass reference variable without a cast of the subclass type. Examples can find in When is an explicit object reference casting is required?. The compiler is happy when you explict cast the superclass reference to subclass reference, but the compiler does not care what the actual object holded by the reference. Does it actually have a superclass object, or just a superclass reference holding a subclass object? No answer from compile time but it has to answer this quesiton.
You can not just take a parent object and suddenly turn it into a child though. The parent object is not an instance of the subclass. If the actual object holded by the reference is a superclass object, casting it to a subclass reference result in a compile time error.
In your case B is parent class and C is its child.
class SuperClass {
// ...
}
class SubClass extends SuperClass {
// ...
}
public class Program {
public static void main(String[] args) {
// case 1: actual SuperClass object
SuperClass p1 = new SuperClass();
// case 2: SubClass object is referred by a SuperClass reference
SuperClass p2 = new SubClass();
SubClass s1 = (SubClass) p1; //run time error
SubClass s2 = (SubClass) p2; //OK
}
}
In Android findViewByIdreturns instance of View Class. Which is a direct superclass of TextView and other view elements.
So if you want to replicate something like that, then you can do something like this:
class Test {
public static void main(String args[]) {
A a = new A();
C c = (C)a.getViewByid('c');
c.f();
}
}
class A {
public B getViewByid(char c) {
B b = null;
switch (c) {
case 'b':
b = new B();
break;
case 'c':
b = new C();
break;
default:
b = new B();
}
return b;
}
}
class B {
public void f() {
System.out.println("Class B");
}
}
class C extends B {
public void f() {
System.out.println("Class C");
}
}
In this program
class a
{
int a=25;
public void aa()
{
System.out.println(a);
}
}
class b extends a
{
int a=2;
public static void main(String[] args) {
b x=new b();
x.aa();
}
}
why does "x.aa()" prints 25 ans why not 2?,what is the reason behind it?
class a
{
int a=25;
public void aa()
{
System.out.println(a);
b();
}
public void b()
{
System.out.println("this should print");
}
}
class b extends a
{
int a=2;
public static void main(String[] args) {
b x=new b();
x.aa();
}
public void b()
{
System.out.println("this should not print");
}
}
and if we consider the above output,then here again the output of b() of above should print "this should print" but we are getting the ouput from sublcass "this should not print"
Class b inherits class A, so when you call x.aa, it is calling method aa of class a. The member a of class a is initialized with 25 so it prints 25. Class a does not know about the member a of class b.
Fields cannot be overridden, and are not virtual. B.a* is independent of A.a, to the point that they can actually have different types. There is no way for B to make A aware of B.a in place of A.a. Instances of B will actually have two fields named a, but one is hidden ("shadowed") by the other. (If desired, code B can refer to its A.a field by writing ((A)this).a. This is because the appropriate a is selected based on the type of ((A)this), which is A, rather than the runtime type of the instance, which would be B or a subtype of B.)
* Note: I have renamed your classes to A and B: per the Java naming conventions, class-names begin with uppercase letters.
b x=new b();
while you will do this this will print out put of the constructor as its giving because its clearly making the object of b class and while in the case of class A in that class that b() act as the method so it wont call when you are making object of class b.
while in the case of
b x=new b();
x.aa();
this it will by default call the inheritance and will print as u getting output.
and one more thing.
public void aa()
{
System.out.println(a);
}
in the case of this it will use the local variable of that particular class so it will print whatever you have defined on that class. in your case that is a=25;
by the way nice question.
method aa() is member of class a. so, method aa() can see/access instance member of class a.
Now, you have inherited class a to b. it means object of class b can access/call aa(). but, it doesn't mean that aa() is allowed to access variable a of class b. thats why method aa() is printing the variable a of it's own class and prints 25.
now about your second program. in class b, you are overriding method b(). while calling an overridden method, the selection of method(whether from sub class or super class) is done on the basis of instance of a invoking object(whether sub class or super class respectively).
you have called method aa() with the instance of class b that is why method b() of class b is called.
I have 3 classes A,B and c as follows
A.java
class A
{
protected A(){
System.out.println("A");
}
void show()
{
System.out.println("showA");
}
}
B.java
class B extends A
{
B(){
System.out.println("B");
}
void show()
{
System.out.println("showB");
}
}
C.java
class C extends B
{
C(){
System.out.println("C");
}
void show()
{
System.out.println("showC");
}
public static void main(String... args)
{
A a= (B)new C();
a.show();
}
}
When executed gives the output
D:\java\rmi\Hello>javac C.java
D:\java\rmi\Hello>java C
A
B
C
showC
I know a superclass cannot be casted to a subclass.But in the output why is it executing the C class method (show) when there is a cast to the super class B?
A a= (B)new C();
And if this is right then what is it that is getting casted to B?
I mean here new C() would call the C constructor and hence the respective outputs but
what is the difference between new C().show(); and (B)new C().show(); what is getting casted here?
Casting an object does not change its type.
(B) new C();
will still create an object of type C, no matter what you cast it to. But if you only create a B it will of course only ever be a B which is why C’s constructor is not called when you execute
(C) new B();
The error "B cannot be cast to C at C.main" means that the superclass B is casted by C which is a subclass.(Just read it again and again and you will understand it..)
You can cast in lower element in the hierarchy with the upper element but not vice-verse..
Hope you got it :)
Class B does not extend C, so it has no knowledge of it and connot be casted to C. With java, you can down cast but not upcast.
OK:
A a= (B)new C();
-> C inherits from B, so cast is possible
Not OK
A a= (C)new B();
-> B does not inherit from C, so it cannot be cast to it
see also: Downcasting in Java
Edit:
Please consider to edit your question, as most users tend to correct an error first. (Remove the error and break it down to your original question)
"what is the difference between new C().show(); and (B)new C().show();"
This is called 'polymorphism'. there is no difference between the two calls, as java will always execute the method of the lowest level of the hierarchy.
For example:
class Bird{
public void fly(){
System.out.println("I am flying");
}}
class Duck extends Bird{
public void fly(){
System.out.println("I can not fly");
}}
class Test{
public static void main(String[] args){
Bird[] birds = {new Bird(), new Duck()};
for (Bird b: birds){
b.fly();
}
}
This would output:
I am flying
I cannot fly
When you are creating an object of a class, its superclass objects are created first.
So when you says
A a = (B)new C();
While creating object of C, its superclass objects are first created. So the object of C can be casted to B.
But in the later case while creating the object of B, it would not possible.
Always remember that a subclass object can be casted into superclass, where as a superclass object can not be casted to its subclass, which is done by you in the second case, so it gives you compilation error.
class a extends b {
void h() {
System.out.println("class a");
}
public static void main(String[]args) {
b x = new a();
c y = new b();
c z = new a();
x.h(); //output class a
y.h(); //output class b
z.h(); //output class a
}
}
class b extends c {
void h() {
System.out.println("class b");
}
}
class c {
void h() {
System.out.println("class c");
}
}
Whats is the precedence in which it checks which method to call. I am confused as to how the JVM decides which method to call when I use dynamic dispatch. The output in this case is
class a
class b
class a
and when I remove the overridden method from class a the output is
class b
class b
class b
The class used depends on the instantiated type. So if you have an instance of class a (via new a()), then whether the declared variable is of type a, b, or c does not matter for the purpose of which definition of h() is invoked (it will always invoke a.h()).
However, where the declared type does matter is in when choosing an overloaded method. If you have a subclass that overloads an overridden method, then when invoking from a variable declared as the parent class, you will never use the overloaded method. If using a variable declared as being of the subclass, then it will use the overloaded method as appropriate.
class A is abstract and class B extends class A
now class A reference can hold object of class B,that is
A aObj = new B();
and assume class B has some extra methods....
like
class A
{
public show();
}
class B extends A
{
public show(){}
public method1(){}
private method2(){}
}
now tell me what things variable aObj can access from class B
can it access everything?
aObj only sees the public show() method. If you cast aObj to B, you can then access public method1(). public method2() is only accessible to the implementation of B.
For reference and completeness, here's a list of the possibilities:
A aObj = new B();
aObj.show(); // Works
aObj.method1(); // Error
aObj.method2(); // Error
And with casting to B:
B bObj = (B)aObj; bObj
bObj.show(); // Works
bObj.method1(); // Works
bObj.method2(); // Works inside bObj, but error otherwise
aObj can only use show() as the compiler thinks aObj is of type A, and the only known method of A is show().
If you know that you actually have a B you can cast that object to a B:
if (aObj instanceof B.class) {
B bObj = (B) aObj;
bObj.method1(); //OK
} else {
log.debug("This is an A, but not a B");
}
aObj.show();