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

3

13

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.

Gavriella answered 24/6, 2014 at 10:42 Comment(2)
It wouldn't make sense. If it were allowed, you could have fields/methods that you'd expect to be there that aren't actually there. If it were allowed, I think the language designers might have been locked away somewhere where they couldn't do any more damage.Kunming
what do you expect would happen?Manumit
S
26

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.

Scourge answered 24/6, 2014 at 10:48 Comment(2)
How about Employee e= new SalesPerson(); e.met2(); I think it is possible but how? compile time doesn't have met2() method. Should not it throw error?Season
@Season not allowed. it will give an error at compile time since there is no met2() method in EmployeeBelisle
K
6

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.

Kunming answered 24/6, 2014 at 10:56 Comment(0)
P
4

If you inherit from a class, you always specialize the common behavior of the super class.

In your example, the SalesPerson is a special Employee. It inherits all behavior from the super class and can override behavior to make it different or add new behavior.

If you, as it is allowed, initialize a variable of the super type with an instance of the sub type like Employee e = new SalesPerson(), then you can use all common behavior on that variable.

If instead, you were possible to do the other way round, there might be several uninitialized members in the class.

You find this very often when using the Java Collection API, where for example you can use the common List class on operations like iterating through it, but when initializing it, you use for example the sub class ArrayList.

Pylorus answered 24/6, 2014 at 10:53 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.