在实例化(子)类时,"类型"是什么区别?你将对象声明为?

时间:2013-02-01 10:37:50

标签: java inheritance subclass instantiation

假设我有一个名为ParentClass的班级和一个名为ChildClass

的班级

ParentClass是抽象的,ChildClass扩展了每个Java术语的ParentClass。此外,ParentClass有一个构造函数,它将int作为参数。现在在另一个类中,我想实例化ChildClass。我尝试了以下两种方式:

  1. ChildClass obj1 = new ChildClass(5)
  2. ParentClass obj2 = new ChildClass(5)
  3. Java允许我使用上述两种方法中的任何一种。我的问题是,实际上有什么区别吗?如果我愿意,我可以互换使用这两种吗?

6 个答案:

答案 0 :(得分:5)

两者都有效,并且都在内存中创建相同的对象。但只有第一个允许您使用ChildClass其他特定的属性或ParentClass不知道的方法。

示例:

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

因此,只有在您确定永远不需要特定子方法或属性(如果有)时才使用第二个实例化方法。

答案 1 :(得分:2)

创建的对象实际上是相同的。

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

   obj1.aMethodNotInParentClass();

编译时

   obj2.aMethodNotInParentClass();

没有。

或者,使用第二种形式允许您更容易地将内部类替换为其他实现。如果您想使用AnotherChildClass代替ChildClass

      ParentClass obj2 = new AnotherChildClass(5);

是你需要做的所有改变(假设正确定义了类);使用第一种方法可能需要在代码的其他位置进行一些更改。

根据经验,将变量定义为更通用的类,它定义(*)对象所需的所有方法。因此,如果您使用ChildClass中未定义的任何ParentClass方法,请使用第一种方法,否则请使用第二种方式。

(*)请注意,我提到定义,而不是实施。如果覆盖ChildClass中的方法,则将使用该实现,因为创建的对象属于该类。

答案 2 :(得分:2)

在内存中将使用完全相同的对象。但是,您只能使用变量obj2,就好像它包含ParentClass对象一样,而不会理解ChildClass类的所有优秀功能。如果ChildClass声明了方法f(),但ParentClass没有声明,则调用obj2.f()将无效 - 尽管内存中的对象可以完美地运行该方法。

答案 3 :(得分:1)

  • 如果他们有相同的方法只是孩子实现了 抽象方法则没有任何区别。
  • 如果你已经添加了aditional方法,那么孩子就不会这样做 如果您将其声明为父母,则可以访问。

答案 4 :(得分:1)

第二种选择只允许使用ParentClass中声明的方法。例如:

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.

    }
}

答案 5 :(得分:0)

是的,有区别。 第一种方法使用动态绑定为您提供子实例作为父对象。这仅为您提供父对象在子实例上的功能。 第二种方法将为您提供子对象的实例作为子对象,允许您使用其所有方法及其父对象方法,而不是仅限于父类的方法。