Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/377.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 是OOP&;完全避免实现继承是可能的吗?_Java_Oop - Fatal编程技术网

Java 是OOP&;完全避免实现继承是可能的吗?

Java 是OOP&;完全避免实现继承是可能的吗?,java,oop,Java,Oop,我将选择Java作为一个例子,大多数人都知道它,尽管其他所有的OO语言都在工作 与许多其他语言一样,Java具有接口继承和实现继承。例如,一个Java类可以从另一个类继承,每个有实现的方法(假设父类不是抽象的)也会被继承。这意味着接口是继承的,该方法的实现也是继承的。我可以覆盖它,但我不必。如果我不覆盖它,我就继承了实现 然而,我的类也可以“继承”(不是Java术语)一个接口,而不需要实现。实际上,在Java中,接口的名称就是这样的,它们提供接口继承,但不继承任何实现,因为接口的所有方法都没有实

我将选择Java作为一个例子,大多数人都知道它,尽管其他所有的OO语言都在工作

与许多其他语言一样,Java具有接口继承和实现继承。例如,一个Java类可以从另一个类继承,每个有实现的方法(假设父类不是抽象的)也会被继承。这意味着接口是继承的,该方法的实现也是继承的。我可以覆盖它,但我不必。如果我不覆盖它,我就继承了实现

然而,我的类也可以“继承”(不是Java术语)一个接口,而不需要实现。实际上,在Java中,接口的名称就是这样的,它们提供接口继承,但不继承任何实现,因为接口的所有方法都没有实现

现在有了这个,你可能会喜欢读它(至少是第一页的前半部分),它非常有趣。它避免了类似的问题。到目前为止,这一切都很有意义,文章中提到的许多其他事情对我来说也很有意义

关于这一点,让我感到困扰的是,实现继承意味着代码重用,这是OO语言最重要的属性之一。现在,如果Java没有类(如本文所说的Java教父James Gosling所希望的那样),它解决了实现继承的所有问题,那么如何使代码重用成为可能呢

例如,如果我有一个类Car,而Car有一个方法move(),该方法使汽车移动。现在,我可以为不同类型的汽车分类,这些都是汽车,但都是汽车的专用版本。有些可能会以不同的方式移动,它们无论如何都需要覆盖move(),但大多数只会保留继承的移动,因为它们的移动方式与抽象的父车一样。现在假设Java中只有接口,只有接口可以相互继承,一个类可以实现接口,但所有类都是最终类,因此没有任何类可以从任何其他类继承

当您有一个接口Car和数百个Car类时,如何避免需要为它们中的每一个实现相同的move()方法?在OO世界中,除了实现继承之外,还有哪些代码重用的概念

有些语言有混音。Mixins是我问题的答案吗?我读过关于它们的文章,但我真的无法想象mixin在Java世界中会如何工作,以及它们是否真的能解决这里的问题

另一个想法是,有一个类只实现Car接口,我们称之为AbstractCar,并实现move()方法。现在,其他汽车也实现了汽车接口,它们在内部创建了AbstractCar的实例,并通过在其内部抽象汽车上调用move()来实现自己的move()方法。但这难道不是白白浪费资源(一个只调用另一个方法的方法——好吧,JIT可以内联代码,但仍然可以)并且使用额外的内存来保存内部对象吗?您甚至不需要实现继承?(毕竟每个对象都需要更多的内存,而不仅仅是封装数据的总和)对于程序员来说,编写这样的伪方法不是很尴尬吗

public void move() {
    abstractCarObject.move();
}
?


任何人都可以想象一个更好的主意,如何避免实现继承,并且仍然能够轻松地重用代码?

您还可以使用组合和策略模式


这比使用基于继承的行为要灵活得多,因为它允许您在运行时通过根据需要替换新车型进行更改。

您可以使用。在您的示例中,一个Car对象可能包含另一个名为Drivetrain的对象。汽车的move()方法可以简单地调用其传动系的drive()方法。反过来,传动系类可以包含发动机、变速箱、车轮等对象。如果您以这种方式构建类层次结构,您可以通过将简单零件的不同组合(即重用代码)组合起来,轻松创建以不同方式移动的汽车。

您应该阅读设计模式。您会发现,接口对于许多类型的有用设计模式都是至关重要的。例如,抽象不同类型的网络协议将具有相同的接口(到调用它的软件),但由于每种类型协议的不同行为,代码重用很少

对于一些算法来说,展示如何将编程中的无数元素组合在一起以完成一些有用的任务是大开眼界的。设计模式对对象也有同样的作用。演示如何以一种方式组合对象以执行有用的任务


要使混合/合成更容易,请查看我的注释和注释处理器:

具体而言,mixin示例:


请注意,如果委托的接口/类型具有参数化方法(或方法上的参数化类型),则当前不起作用。我正在研究…

简短回答:是的,这是可能的。但是你必须有目的地去做,而不是偶然的(使用最终的、抽象的、设计的、考虑继承的等等)

长答覆:

好吧,继承实际上不是为了“代码重用”,而是为了类“专门化”,我认为这是一种误解

例如,仅仅因为向量相似,就从向量创建堆栈是一个非常糟糕的想法。或哈希表中的属性,因为它们存储值。见[有效]

“代码重用”更像是OO特性的“业务视图”,这意味着您可以轻松地在节点之间分配对象;并且是可移植的,没有上一代编程语言的问题。这已被证明是正确的。我们现在有了易于分发的图书馆;例如,在java中,jar文件可以用于任何项目,从而节省数千小时的开发时间。乌斯蒂尔
public class Car
{
  private ICar _car;

  public void Move() {
     _car.Move();
  }
}
interface Stack<T> {
   public void push(T object);
   public T pop();
   public void clear();
   public int size();
}