class Superclass
{
    void display()
    {
        System.out.println("Super");
    }
}

class Sub1 extends Superclass
{
    void display()
    {
    System.out.println("sub class1");
    }
}
class Sub2 extends Sub1
{
    void display()
    {
        System.out.println("Sub class2");
    }

    void display2()
    {
        System.out.println("Second method");
    }
}


public class reference {

    public static void main(String[] args)
    {
        Superclass ref=new Sub1();
        ref.display();
        ((Sub2)ref).display();
    }



}

I am trying to invoke a Sub2 class specific method using Superclass reference but throws a ClassCastException.Any help in explaining why??

Edited 3 Years Ago by Nick Evan: Fixed formatting

throws a ClassCastException

Please show full text of the error message.

What type is ref1? The JVM says it is not a Sub2. Sub2 could have members not in Sub1.

1. You can't invoke a subclass specific method using superclass reference as the super class
does not have any information of the details of the subclass.
However in this case you will get a compilation error.

2. You can't instantiate a Superclass variable and then cast it to subclass, but the reverse is true, i.e. you can instantiate a sub class variable and then cast it to super class.

Following code will not work -

Superclass ref=new Sub1();
((Sub2)ref).display();

But the following code will work fine -

Superclass ref=new Sub2();
((Sub1)ref).display();

class Superclass
{
void display()
{
System.out.println("Super");
}
}

class Sub1 extends Superclass
{
void display()
{
System.out.println("sub class1");
}
}
class Sub2 extends Sub1
{
void display()
{
System.out.println("Sub class2");
}

void display2()
{
System.out.println("Second method");
}
}


public class reference {

public static void main(String[] args)
{
Superclass ref=new Sub1();
ref.display();
((Sub2)ref).display();
}

}

I am trying to invoke a Sub2 class specific method using Superclass reference but throws a ClassCastException.Any help in explaining why??

Edited 6 Years Ago by java_programmer: n/a

It is not possible to call a method of any sub class from a instance of superclass.
Although u can call methods defined in superclass by a instance of sub class.

sub1 ref=new sub1();
      ref.display();

The reason for this is that when you instantiate a subclass its constructor automatically calls the constructor(s) of it superclasses, so all the variables etc associated with the superclasses are initialised properly. However, when you instantiate the superclass none of the subclass contructors are called, so none of the subclasses are initialised, and their methods are unavailable.

The reason for this is that when you instantiate a subclass its constructor automatically calls the constructor(s) of it superclasses, so all the variables etc associated with the superclasses are initialised properly. However, when you instantiate the superclass none of the subclass contructors are called, so none of the subclasses are initialised, and their methods are unavailable.

Hi James,
By far your reply seems a bit closely related to my problem. But i am just giving a Super class reference to a subclass object.I am instantiating a sub class. I am trying to run the overridden "display()" method in Sub2 creating a Sub1 object. Is it possible??

Please show full text of the error message.

What type is ref1? The JVM says it is not a Sub2. Sub2 could have members not in Sub1.

Hi Norm,

there is no reference variable named ref1. Its ref. And my question is i am giving a super class reference(Superclass) to its subclass(Sub1) object and i am trying to run an overridden method in the sub sublclass(here sub2).I wanna know why there is a run time exception giving me a CLassCastException. Following is the output i get:

sub class1
Exception in thread "main" java.lang.ClassCastException: Sub1 cannot be cast to Sub2
at reference.main(reference.java:36)

So you have a reference variable "ref" declared to hold a reference to an object of type Superclass. That means it can also hold a ref to an object of type Sub1 or Sub2, OK so far. However, if that's how it is declared then the compiler will error any attempt to call methods only defined in Sub1 or Sub2 because all the compiler knows is that the referred object is a Superclass object.
At run time, the JRE knows the exact kind of every instatiated object, so if ref refers to a Sub2, the JRE knows that. If your code calls a Superclass method that's overidden in Sub2 the JRE will call the Sub2 version, regardless of how the reference variable was declared.
You can use run-time casting to inform the compiler that ref now contains a reference to an object of type (say) Sub2. In general the compiler cannot tell whether that will be true or not when the program is run, in which case it will allow the code to compile and trust that you know what you are doing. If you are wrong then the JRE will detect that at run time and throw a class cast exception.
So, this example works

Superclass ref=new Sub2();
((Sub1)ref).display()

because at run time ref contains a reference to a Sub2 and, by definition, all objects of type Sub2 are also objects of type Sub1 and of Superclass.

This example fails

Superclass ref=new Sub1();
((Sub2)ref).display();)

because because at run time ref contains a reference to a Sub1 which, by definition is NOT a Sub2.

This common real-life example

ObjectInputStream inbound = (create some valid object inout stream);
ref = (Superclass) inbound.readObject();

will work, or not work, depending entirely on whether the Object returned by readObject() happens to be a Superclass object or not whenever that code is executed.
Regardless of how you play with reference variables and casting, it is not possible to invoke Sub2's version of a method using an object which is really an instance of Sub1. The reason for this is, as I wrote previously, because there is no instantiated Sub2 context for the method to execute in, just Sub1 (and therefore Superclass) contexts.

Yes. In super class you may define a method to invoke the method of the subclass so that you may call the method with the super class reference.

class Superclass{
void display(){
System.out.println("Super");
}

void Sub2Display(){  // the extra method you define to call the method of its subclass
	Sub2 sub2= new Sub2();
	sub2.display();
	}
}

class Sub1 extends Superclass{
void display(){
System.out.println("sub class1");
}
}
class Sub2 extends Sub1{
void display(){
System.out.println("Sub class2");
}

void display2(){
System.out.println("Second method");
}
}


public class reference {
public static void main(String[] args){
Superclass ref=new Sub1();
ref.display();
ref.Sub2Display(); //invoke the method of the subclass with the super class reference
//((Sub2)ref).display();
}
}

Edited 6 Years Ago by tong1: n/a

tong1: Hi.
Your code is valid, but it's not what the O/P needs, except in the trivial case where then method can (and should) be static. You will execute display() in the context of a new Sub2 that you have created. That is not the same as executing it in the context of an existing object whose instance variables you do not have access to.
Eg: suppose the Superclass defines Date whenInstantiated; and initialises this to new Date() in its default constructor. Add this info into what is displayed in each version of display(). Your code will display the whenInstatiated of the new Sub2 you create, not the whenInstantiated of the Sub1 created on line 30, which is what the O/P wants.

This question has already been answered. Start a new discussion instead.