java - 使用抽象类构造堆
问题描述
我对抽象类代码的实际实现以及它的意义感到有些困惑。
我为 Max Heap 编写了代码,并且我想基于它创建一个抽象类,这样我就可以对不仅仅是“Max”堆的堆有一个大致的轮廓。
我的 MaxHeap 的主体如下所示:
public class MaxHeap {
// A class for nodes, just has 3 fields, lchild, rchild, and value
private HeapNode top;
private List<HeapNode> heap;
public MaxHeap() {
this.top = null;
this.heap = new ArrayList<>();
}
//I won't go into the guts of these methods, but will explain
//Displays the heap like [1,2,3,4,5,...]
public void display() {...}
//Adds a new HeapNode to the end of heap, if empty sets to top
public void add(int value) {...}
//Deletes a HeapNode at index pos
public void delete(int pos) {...}
//Swaps 2 Nodes within the heap
protected void swap(int pos, int otherPos) {...}
//// These are the methods that actually differ depending on the
//// type of heap (maxheap, minheap, etc) so I would assume they
//// would be abstract methods if writing an abstract class?
|
|
V
//Called within add method, heapifys the heap after adding a new Node
protected void addHeapify(int pos) {...}
//Called within delete method, heapifys the heap after deleted Node
protected void deleteHeapify(int pos) {...}
//Called within deleteHeapify for "if (pos==0) {...}", delete max Node
protected deleteExtremum() {...}
}
我的问题反映了我将如何在更抽象的层面上实现这一点?我想将我的编码提升到一个新的水平,并且需要理解这一点。我会做一个这样的抽象类吗?
public abstract class Heap {
private HeapNode top;
private List<HeapNode> heap;
public Heap() {...}
// **************
// public methods
// **************
public void display() {...}
public void add(int value) {...}
public void delete(int pos) {...}
// ******************
// non-public methods
// ******************
protected void swap(int pos, int otherPos) {...}
// ****************
// abstract methods
// ****************
protected abstract void addHeapify(int pos);
protected abstract void deleteHeapify(int pos);
protected abstract void deleteExtremum();
}
了解“抽象化”原始课程的正确方法将对我有很大帮助。
在抽象类中添加字段和构造函数是否正确,即使添加、删除、交换和显示不会在不同的堆之间发生变化,这些方法也应该是抽象的吗?
我也想知道是否应该改用接口,但它似乎是一个更严格的抽象类,我将无法定义添加、删除、交换和显示。
解决方案
抽象类是几个具体类的泛化。它用于共享通用功能和数据。由于它是抽象的,如果没有一些定制,它就不能被实例化(使用)。如果该类可以按原样使用,则它不是抽象的。
如果您需要针对接口的抽象类,重要的一点是抽象是否包含数据。您可以拥有带有数据字段和只有抽象方法的抽象类。
当您的通用功能需要一些特定于继承者的数据或处理时,应该使用抽象方法。就像您的add
方法是否出于某种原因需要调用addHeapify
,但不关心它是采用哪种方式实现的。
如果您需要所有后代都有一些方法,但它没有用于通用功能,那么使用接口是明智的,因为接口定义了类的行为方式,但没有定义它包含哪些数据。因此,您可以抽象出两个包含不同数据的类。在 Java 8 中,您可以default methods
直接在接口中实现(以前不可能),因此只有在有公共数据要存储在其中时才需要抽象类。
请记住,其他算法可以使用对抽象类或接口的引用来调用您的算法,而无需知道引用背后的实现是什么。这主要用于使代码可变,因为您可以替换接口或抽象类的任何实现,而无需更改客户端代码。
推荐阅读
- javascript - 模拟红绿灯
- python - 如何将 Pandas 中的多标题 Excel 转换为简单表
- css - 我无法让组件在 Angular2 中显示为内联块
- php - Codeignigter 控制器不返回 JSON
- delphi - 如何为通过批量电子邮件 API 发送的电子邮件附件生成多部分/表单数据
- sql-server - SSIS - 连接管理器的最佳实践 - 由参数组成?
- php - Wordpress Shortcode 循环遍历数据并将当前循环记录发送到自定义插件中的其他 Shortcode
- .net - 如何正确设置 dotnet 核心类库以在 Azure DevOps 中发布到 NuGet 源?
- javascript - 如何按对象数组过滤?
- css - 使用 codepen 创建烟花动画的问题