When instantiating a (sub)Class, is there any difference in what “type” you declare the object as?

人走茶凉 提交于 2019-12-04 17:19:08

Both work, and both create the same object in memory. But only the first one will allow you to use ChildClass additional specific properties or methods the ParentClass doesn't know about.

Example :

abstract class ParentClass{
   ...
}

class ChildClass extends ParentClass {

   public void SomeChildMethod(){ ... }
   ...
}

...


ChildClass obj1 = new ChildClass(5);
ParentClass obj2 = new ChildClass(5);

obj1.SomeChildMethod(); // ok
obj2.SomeChildMethod(); // compilation error 
((ChildClass)obj2).SomeChildMethod(); // ok

So, use the second instantiation method only if you're sure you'll never need the specific child methods or properties, if any.

The created object is effectively the same.

The first method allows you to use methods defined in the ChildClass and not in ParentClass. So

   obj1.aMethodNotInParentClass();

compiles while

   obj2.aMethodNotInParentClass();

does not.

Alternatively, using the second form allows you to replace the inner class with other implementation more easily. If you want to use AnotherChildClass instead of ChildClass,

      ParentClass obj2 = new AnotherChildClass(5);

is all the change you need to do (assuming classes are properly defined); using the first method will probably need some changes in other places of your code.

As a rule of thumb, define the variables as the more general class that defines(*) all the methods you need of the object. So, if you use any method of ChildClass that is not defined in ParentClass, use the first way, otherwise, use the second.

(*) Note that I mention definition, not implementation. If you override a method in ChildClass, you will use that implementation because the object created is of that class.

In memory the exact same object will be used. However, you can only use the variable obj2 as if it contained a ParentClass object without taking for granted all the nice functionality of your ChildClass class. If ChildClass declares a method f(), but ParentClass does not, the call obj2.f() will not work - although the object in memory could be able to run the method perfectly well.

  • If they have the same methods just that the child implements the abstract method then there isn't any difference.
  • If you have added aditional methods the the child then thoose won't be accessible if you declare it as a parent.

The second alternative will only allow to use methods declared in the ParentClass. For example:

public class ParentClass {
    public void doX() {}
}

public class ChildClass {
    public void doY() {}

    public static void main() {
        ParentClass p = new ChildClass();
        ChildClass c = new ChildClass();
        p.doX(); //works
        c.doX(); //works

        p.doY(); //not allowed
        c.doY(); //works


        ((ChildClass) p).doY(); //this way you cast the object to ChilClass and can use its methods.

    }
}

Yes there is a difference. The first way uses dynamic binding to give you a child instance as a parent object. This only gives you the functionality of the parent object onto the child instance. The second way will give you an instance of the child object as the child object, allowing you to use all of its methods and its parent objects methods rather than being limited to the methods of the parent class.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!