这是滥用OOP和Java吗?

时间:2018-04-17 21:00:28

标签: java oop

让我们说你有这个课程:

import java.util.ArrayList;

public class Array
{
  private ArrayList<Object> a = new ArrayList<Object>();

  public void add(Object element)
  {
    a.add(element);
  }

  public void addAll(Object elements[])
  {
    for (int i = 0; i < elements.length; ++i)
      a.add(elements[i]); // this line is going to be changed
  }
}

这个派生类:

public class ArrayCount extends Array
{
  private int count = 0;

  @Override
  public void add(Object element)
  {
    super.add(element);
    ++count;
  }

  @Override
  public void addAll(Object elements[])
  {
    super.addAll(elements);
    count += elements.length;
  }
}

如果在基类中,我们进行以下更改:

  public void addAll(Object elements[])
  {
    for (int i = 0; i < elements.length; ++i)
      add(elements[i]); // this line was changed
  }

我希望调用基类中的add()方法,而不是派生类中重写的add()。为什么不是这样?这个例子是滥用OOP吗?

4 个答案:

答案 0 :(得分:2)

Java将始终调用运行时类的方法实现(运行时的真实对象类),只要它是有效的方法覆盖。这称为动态绑定。

你没有滥用,而是利用有保证的功能。

你所拥有的设计在Java中是合法的,但出于多种原因这是一种不好的做法,你突出了一个重要的原因。这是有时不鼓励实现继承的主要原因之一,支持接口继承。

答案 1 :(得分:0)

在一天结束时,它归结为运行时发生的事情。

由于函数是add(),它将调用add() this对象,这是在运行时被覆盖的函数。

这是封装的全部要点,子类应该完全控制其方法的作用。

答案 2 :(得分:0)

  

我希望调用基类中的add()方法,而不是派生类中重写的add()。为什么不是这样?

Java使用动态分派(也称为动态绑定)在运行时绑定方法。简单来说,这意味着当在基类上调用方法时,执行的方法是对象的实际类型。请参阅Wikipedia articleJava reference on polymorphism

  

此示例是滥用OOP吗?

对于一个展示动态调度的人为例子,它并不坏。对于其他任何事情,这都是毫无意义的。

答案 3 :(得分:-1)

我认为以下更改可以解决问题:

  

如果在基类中,我们进行以下更改:

  public void addAll(Object elements[])
  {
    for (int i = 0; i < elements.length; ++i)
      super.add(elements[i]);     // <-- new use of SUPER
  }

基本上,如果您希望某些方法不变(总是做同样的事情),您必须声明它们final以防止覆盖。否则,派生类可以实现他们想要的任何东西。

的修复是编写文档,解释任何派生方法必须遵循的合同。)