创建对象时声明的基类/接口或实现?

时间:2016-10-27 09:27:42

标签: java polymorphism

我有这个问题。假设代码1是 Java with runtime polymorphism ,代码2是 Java而没有运行时多态

代码1:

class A {
    void run() { System.out.println("A is running"); }
}

class B extends A{
    void run(){ System.out.println("B is running with A!");}

    public static void main(String args[]){

        A a = new B(); //referenced to class A
        a.run();

    }
}

代码2:

class A {
    void run(){System.out.println("A is running");}
}

class B extends A{
    void run(){ System.out.println("B is running with A!");}

    public static void main(String args[]){
        B a = new B(); //referenced to the same constructor class
        a.run();
    }
}

尽管这两个代码给出了完全相同的结果,但众所周知,运行时多态性在OOP中非常重要。我需要使用代码1而不是使用代码2的解释/原因。

2 个答案:

答案 0 :(得分:1)

让我们来看看这个案例:
您有多个继承自同一基类的类,您希望在所有类上调用它们的共享函数run(),即使它们是不同的类。 你必须这样做:

interface A{
    void run();
}

class B implements A{
void run(){ System.out.println("B is running with A!");}

class C implements A{
void run(){ System.out.println("C is running with A!");}

public static void main(String args[]){
    Array<A> objects = new Array<A>();
    objects.put(new B()); //Object are stored as instances of "A"
    objects.put(new C());
    objects.put(new B());
    for (A obj : objects)
        obj.run();//Calls everything
}

答案 1 :(得分:1)

在每种情况下都不需要在OOP中利用多态性 多态性是一种在需要灵活性时带来灵活性的机制。

例如,在您的情况下,写下:

B a = new B();

A a = new B()

取决于您是否需要并且有兴趣引用基类而不是子类作为变量的声明类型。

引用基类(此处为A)允许其中的许多内容(它不是详尽但频繁的用例):

  • 屏蔽实现(通过工厂或注入依赖)。通过这种方式,您可以在不中断客户端代码调用的情况下更改实现(返回CD扩展A)。在您的代码中,您不会执行此操作,但在实际应用程序中,您可以满足此需求。
  • 如果您有AB类的通用处理,您可以提出一种方法,该方法将A类型的实例作为参数。 示例: public void doProcess(A instance)
    在这种情况下,如果您声明B a = new B(),则代码将无法编译 如果您将此实例作为语义传递给该方法,则B实例为A,但A实例不是 必须是B

通常,我们可以阅读声明界面,而不是实现是一个好习惯。事实上,在大多数情况下,但在其他一些情况下,事实并非如此。举个例子,如果您需要使用TreeMap,则不会声明接口Map,因为TreeMap的行为非常具体且有特殊要求,因此您可能需要强调上。当您实例化经典HashMap时,通常情况下,由于其界面足够,您不必将HashMap视为声明类型。您没有兴趣与实现建立更强大的耦合。