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

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/gwt/3.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 为了最大限度地重用和提高效率,正确的OO设计是什么?_Java_Oop_Inheritance - Fatal编程技术网

Java 为了最大限度地重用和提高效率,正确的OO设计是什么?

Java 为了最大限度地重用和提高效率,正确的OO设计是什么?,java,oop,inheritance,Java,Oop,Inheritance,假设我有一个Java包(包括.jar和源代码)。下面是一些我想重用的类的定义 abstract class Tree { public abstract Tree[] children(); public void print(); } class LabeledTree extends Tree implements Label { Label label; Tree[] daughterChildren; public Tree[] children(); } cla

假设我有一个Java包(包括.jar和源代码)。下面是一些我想重用的类的定义

abstract class Tree {
  public abstract Tree[] children();
  public void print();
}

class LabeledTree extends Tree implements Label {
  Label label;
  Tree[] daughterChildren;
  public Tree[] children();
}

class Demo {
  public static void main(String[] args) {
    Parser p = new Parser();
    String[] sent = { "This", "is", "an", "easy", "sentence", "." };
    Tree parse = p.apply(sent);
    parse.print();
  }
}
上面的
apply
方法返回一个
LabeledTree
。现在,我想创建我自己类型的树,比如说
MyTree
,它具有以下结构

class MyTree {
  int value;
  Label label;
  public void myPrint();
}

你建议我把这个类放在继承树的什么地方,这样我就可以直接从
apply
方法实例化这个类的对象了?你认为我应该如何设计我的系统以最大限度地实现软件重用,而不必解析每一棵树来构建
MyTree
的对象?

你的谜题中缺少了一些片段,这使得我无法给出完整的答案,但是作为第一个猜测,我建议将代码泛化,作为实现泛化并允许更容易扩展的第一步

您的谜题中缺少了一些片段,这使得我无法给出完整的答案,但作为第一个猜测,我建议将您的代码泛化,作为实现泛化并允许更容易扩展的第一步

几点评论:

首先,树定义公开了一个重要的细节——每个树对象都是一个节点。这将创建一大堆概念单元。在真正的API中,您将有一个树接口和一个使用节点的实现。所有数据成员都将位于节点中,但根节点除外,根节点将位于TreeImpl中

其次,我非常相信命名是良好可读代码的关键第一步,它通常会影响OO设计的质量。 树不应该简单地实现标签。你能说:“一棵树就是一个标签”吗? 另一方面,如果您有以下情况: “TreeNode实现了HasLabel”,这会更清楚——“您的树节点有一个标签”

第三,您遇到了众所周知的OOP一致性和差异问题。在当前设计中,标记树的根具有标签,但较低的节点(仅为树)不必是标记树。这将是有趣的调试。泛型可以帮助您解决这个问题,但请务必阅读有效的Java,以了解约束泛型类型是如何工作的。

几点注释:

首先,树定义公开了一个重要的细节——每个树对象都是一个节点。这将创建一大堆概念单元。在真正的API中,您将有一个树接口和一个使用节点的实现。所有数据成员都将位于节点中,但根节点除外,根节点将位于TreeImpl中

其次,我非常相信命名是良好可读代码的关键第一步,它通常会影响OO设计的质量。 树不应该简单地实现标签。你能说:“一棵树就是一个标签”吗? 另一方面,如果您有以下情况: “TreeNode实现了HasLabel”,这会更清楚——“您的树节点有一个标签”


第三,您遇到了众所周知的OOP一致性和差异问题。在当前设计中,标记树的根具有标签,但较低的节点(仅为树)不必是标记树。这将是有趣的调试。泛型可以帮助您解决这个问题,但请务必阅读有效的Java,以了解约束泛型类型是如何工作的。

我同意@Uri的观点,将树作为接口而不是抽象类将是一种改进

若您的解析器不知道树的子类,那个么一种方法是使用Class.forName的基于反射的方案。另一种处理方法是使用一个系统,在安装扩展时在该系统中进行注册(这里的一个例子是Eclipse插件注册表,尽管它是这种模式的一个非常复杂的例子)

您更大的问题实际上是关于如何最好地组织用OO语言编写的解析器。关于这个问题有很多很多书。你可以试着看看这本书:

Java编程语言处理器:编译器和解释器 大卫·瓦特(作者)、德里克·布朗(作者)

它可以在Amazon上找到,并且对开始理解如何设计语言解析器很有帮助。这些例子都是用Java编写的

此外,如果您有语法,您可以尝试通过Antlr运行它,并查看输出以获得如何组织解析器的良好示例


我同意@Uri的观点,将树作为接口而不是抽象类将是一种改进

若您的解析器不知道树的子类,那个么一种方法是使用Class.forName的基于反射的方案。另一种处理方法是使用一个系统,在安装扩展时在该系统中进行注册(这里的一个例子是Eclipse插件注册表,尽管它是这种模式的一个非常复杂的例子)

您更大的问题实际上是关于如何最好地组织用OO语言编写的解析器。关于这个问题有很多很多书。你可以试着看看这本书:

Java编程语言处理器:编译器和解释器 大卫·瓦特(作者)、德里克·布朗(作者)

它可以在Amazon上找到,并且对开始理解如何设计语言解析器很有帮助。这些例子都是用Java编写的

此外,如果您有语法,您可以尝试通过Antlr运行它,并查看输出以获得如何组织解析器的良好示例


丢失了哪些零件?关于泛化,你能说得更具体些吗?我宁愿不碰软件包的代码,只添加我自己的代码。缺少哪些部分?关于泛化,你能说得更具体些吗?我宁愿不碰软件包的代码,只添加我自己的代码。