当实例化(子)类,是有什么“型”有什么区别声明的对象?(When instantiating a (

2019-08-16 17:06发布

说我有一个名为类ParentClass和一个叫做类ChildClass

ParentClass是抽象的和ChildClass扩展ParentClass按Java的术语。 此外, ParentClass具有一个构造,其需要一个int作为参数。 现在,在另一个类我想实例化ChildClass 。 我已经尝试了两种方式如下:

  1. ChildClass obj1 = new ChildClass(5)
  2. ParentClass obj2 = new ChildClass(5)

Java允许我使用任何上述两种方式。 我的问题是,是否有任何实际的区别? 我可以用两个,交替如果我想?

Answer 1:

无论工作,都在内存中创建相同的对象。 但是,只有第一个将允许您使用ChildClass的父类不知道其他特定属性或方法。

例如:

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

因此,只使用,如果你相信你会永远需要儿童的具体方法或属性,如果有第二个实例方法。



Answer 2:

创建的对象实际上是一样的。

第一种方法允许您使用在定义的方法ChildClass ,而不是在ParentClass 。 所以

   obj1.aMethodNotInParentClass();

而编译

   obj2.aMethodNotInParentClass();

才不是。

另外,使用第二种形式让你更方便地更换与其他实施内部类。 如果你想使用AnotherChildClass代替ChildClass

      ParentClass obj2 = new AnotherChildClass(5);

是你需要做的(假设类正确定义)的所有变化; 使用第一种方法可能需要在代码中的其他地方的一些变化。

作为一个经验法则,确定你所需要的对象的变量定义(*)更一般的类的所有方法。 所以,如果你使用的任何方法ChildClass未在定义ParentClass中,使用第一种方式,否则,使用第二个。

(*)请注意,我提到的定义 ,而不是实现 。 如果替换的方法ChildClass ,您将使用实现,因为创建的对象是类的。



Answer 3:

在存储器中的完全相同的对象将被使用。 但是,你只能使用变量obj2 ,如果它包含一个ParentClass对象,而理所当然所有的好的功能ChildClass类。 如果ChildClass声明的方法f()ParentClass没有,通话obj2.f()将无法正常工作-虽然在内存中的对象可以是能够运行的方法非常清楚。



Answer 4:

  • 如果他们有相同的方法只是孩子实现抽象方法那么就没有任何差别。
  • 如果您已经添加aditional的方法的孩子,然后,如果你声明它作为父母thoose将无法访问。


Answer 5:

第二种方案将只允许使用在父类中声明的方法。 例如:

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.

    }
}


Answer 6:

是,有一点不同。 第一种方式使用动态绑定来给你一个子实例的父对象。 这只是给你的父对象到子实例的功能。 第二种方法会给你的孩子对象作为子对象的实例,让你使用它的全部方法和其父对象的方法,而不是仅限于父类的方法。



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