prosseek
prosseek

Reputation: 190809

The difference between "C c = new C()" and "A c = new C()" when C is a subclass of A in Java

Let's say we have class A as a parent class, and class C that extends it.

class A
{
    void m()
    {
        System.out.println("A.m");
    }
}

class C extends A
{
    @Override
    void m()
    {
        System.out.println("C.m");
    }
}

What's the difference between reference A a and C c when we use them to point to the same object type, for example A a = new C(); and C c = new C();?

From this question: Java inheritance vs. C# inheritance, it looks like that as a and c points to object type of C, and there seems no difference in using them.

I tested this code, and they all prints C.m.

class inherit {

    void x(A a)
    {
        a.m();
    }

    public static void main(String[] args) {
        System.out.println("hello");
        A a = new C();
        C c = new C();
        a.m();
        c.m();

        new inherit().x(a);
        new inherit().x(c);

    }
}

Upvotes: 3

Views: 1526

Answers (4)

Hui Zheng
Hui Zheng

Reputation: 10224

That depends what the object is going to be used for.

If what you actually need is an object that has A's interface(i.e. A's type), it's strongly recommended to use A a = new C();. This way it makes it clear that you want an A interface, not a C implementation. Later when you change your mind, you can safely change it to A a = new Another_Subtype_Of_A(); without breaking other code.

This is especially true when A is an interface(In your case, A is a class). For example, if you just want a list, List list = new ArrayList(); is clearly better than ArrayList list = new ArrayList();. That's called "programming to interface, not implementation".

If you're creating an object that specifically needs C's interfaces(esp. those not present in A), you'd better choose C c = new C();. If you write A a = new C() instead, sooner or later you still have to cast the object to C(because A doesn't have all of your desired interfaces), so why bother?

Upvotes: 2

asifsid88
asifsid88

Reputation: 4701

firstly A is parent class and C is child class when you do A a = new A() then object of A is created and hold by A handle. When you do C c = new C() then object ofC is creating and C handle holds it.. But when you do A a = new C() then object ofC is created and Ahandle holds it. It means all the properties ofC is now been used. Although handle ofA is used by properties (instance) of C are used. This us polymorphism. Now it will used all the overloaded methods of C and not of A

Usages as an example
The difference come when you create a large project having methods created for child classes
Assume you have hello method
public void hello(C c) { }

In future you have another class B which extends A.. in that case you cannot use hello as its argument is of type C.. And imagine you have many classes as a child of A which need to use such method (then how many such methods you will create). Polymorphism is the rescue
You create hello with A as argument
public void hello (A x) { }
and now you can use same method for all the children of A..
A c = new C()
A b = new B()

Now all can use hello this is the beauty of polymorphism

Upvotes: 0

Dancrumb
Dancrumb

Reputation: 27539

Java is all about Interfaces and Implementations.

An Interface is simply a set of public fields (methods & properties) the describe how users can interact with a class that implements the interface.

An Implementation is the code that actually makes those methods and properties do something. An Implementation can be a class that implements an interface, or it could be a subclass of some other implementation.

When you instantiate a class, you're writing code like:

Interface a = new Implementation();

Often times, we wrap the Interface and the Implementation all together... put another way, when we define a class, whether we're explicitly implementing an interface or not, we're defining an Interface with every public method we write.

Thus, it's the Interface that affects what methods we can call, but it's the Implementation that affects what happens when we call them.

Upvotes: 1

Dennis
Dennis

Reputation: 32598

It's not about the runtime type of the variable. You may only know you have a Vehicle object at compile time and based on user input, that may be a GarbageTruck or SportsCar.

GarbageTruck t;
...
t = new SportsCar();  //can't do this!

// so we do this:
Vehicle t;
if(user.isFast()) {
   t = new SportsCar();
} else {
   t = new GarbageTruck();
}

Upvotes: 1

Related Questions