3

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);

    }
}
Community
  • 1
  • 1
prosseek
  • 182,215
  • 215
  • 566
  • 871
  • 1
    If `C` defines methods not defined in `A`, you won't be able to call them through an `A` reference. Also if a method expects a `C` argument, you can't pass it an `A`. In both cases you'll have to cast `A` to `C`. – Ismail Badawi Feb 17 '13 at 04:15
  • 1
    The difference is, if C had a method that A didn't, it would not be accessible through A a. On the other hand, if you have multiple sub-types of A, and want to treat them all the same for some collection, then casting them as A makes more sense. – kufudo Feb 17 '13 at 04:16

4 Answers4

2

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?

Hui Zheng
  • 10,084
  • 2
  • 35
  • 40
1

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();
}
Dennis
  • 32,200
  • 11
  • 64
  • 79
1

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.

Dancrumb
  • 26,597
  • 10
  • 74
  • 130
0

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

asifsid88
  • 4,631
  • 20
  • 30