Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In java , can we pass superclass Object to subclass reference?

In java, can we pass superclass Object to subclass reference ?

I know that it is a weird question/practically not viable, but I want to understand the logic behind this Why is it not allowed in java.

class Employee {
    public void met1(){
        System.out.println("met1");
    }
}


class SalesPerson extends Employee 
{
    @Override
    public void met1(){
    System.out.println("new met1");
    }


    public void met2(){
        System.out.println("met2");
    }

}

public class ReferenceTest {
    public static void main(String[] args) {

        SalesPerson sales = new Employee(); // line 1

        sales.met1();  // line 2

        sales.met2();  // line 3
    }
}

What would have happened if Java allowed compilation of line 1? Where would the problem arise?

Any inputs/link are welcomes.

like image 798
Rajul Konkar Avatar asked Jun 24 '14 10:06

Rajul Konkar


2 Answers

If your SalesPerson sales = new Employee(); statement was allowed to compile, this would have broken the principles of Polymorphism, which is one of the features that the language has.

Also, you should get familiar with that does compile time type and runtime type mean:

The compile-time type of a variable is the type it is declared as, while the runtime type is the type of the actual object the variable points to. For example:

Employee sales = new SalesPerson();  

The compile-time type of sales is Employee, and the runtime type will be SalesPerson. The compile-time type defines which methods can be called, while the runtime type defines what happens during the actual call.

Let's suppose for a moment that this statement was valid:

SalesPerson sales = new Employee();

As I said, the compile-time type defines which methods can be called, so met2() would have been eligible for calling. Meanwhile, the Employee class doesn't have a met2() and so the actual call would have been impossible.

like image 65
Konstantin Yovkov Avatar answered Oct 12 '22 23:10

Konstantin Yovkov


No. It makes zero sense to allow that.

The reason is because subclasses generally define additional behavior. If you could assign a superclass object to a subclass reference, you would run into problems at runtime when you try to access class members that don't actually exist.

For example, if this were allowed:

String s = new Object();

You would run into some pretty bad problems. What happens if you try to call a String method? Would the runtime crash? Or perhaps a no-op would be performed? Should this even compile?

If the runtime were to crash, you could use runtime checks to make sure the objects you receive will actually contain the methods you want. But then you're basically implementing guarantees that the Java type system already provides at compile-time. So really that "feature" cost you nothing but a bunch of type-checking code that you shouldn't have had to write in the first place.

If no-ops were executed instead of nonexistent methods, it would be extremely difficult to ensure that your programs would run as written when the members you want to access don't exist, as any reference could really be an Object at any point. This might be easy to handle when you are working on your own and control all your code, but when you have to deal with other code those guarantees essentially vanish.

If you want the compiler to do the checking, assuming compiler writers don't hunt you down and give you a stern talking-to -- well, you're back to "normal" behavior once more. So again, it's just a lot of work for zero benefit.


Long story short: No, it's not allowed, because it makes zero sense to do so, and if a language designer tried to allow that they would be locked up before they could do any more harm.

like image 41
awksp Avatar answered Oct 12 '22 23:10

awksp