2

假设我有一个班级ParentClass和一个班级ChildClass

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

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

Java 允许我使用上述两种方式中的任何一种。我的问题是,实际上有什么区别吗?如果我愿意,我可以使用这两者吗?

4

6 回答 6

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

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

于 2013-02-01T10:39:45.863 回答
2

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

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

   obj1.aMethodNotInParentClass();

编译同时

   obj2.aMethodNotInParentClass();

才不是。

或者,使用第二种形式可以让您更轻松地用其他实现替换内部类。如果你想使用AnotherChildClass而不是ChildClass

      ParentClass obj2 = new AnotherChildClass(5);

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

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

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

于 2013-02-01T10:44:11.903 回答
2

在内存中,将使用完全相同的对象。但是,您只能obj2像包含ParentClass对象一样使用该变量,而不会理所当然地认为您的ChildClass类的所有不错的功能。如果ChildClass声明了一个方法f(),但ParentClass没有声明,则调用obj2.f()将不起作用——尽管内存中的对象可以很好地运行该方法。

于 2013-02-01T10:44:59.370 回答
1
  • 如果它们具有相同的方法,只是孩子实现了抽象方法,那么就没有任何区别。
  • 如果您添加了其他方法,那么如果您将其声明为父级,则子级将无法访问。
于 2013-02-01T10:42:11.750 回答
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.

    }
}
于 2013-02-01T10:45:42.850 回答
0

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.

于 2013-02-01T17:20:25.760 回答