Java最佳实践:子类中更详细的类变量
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Java最佳实践:子类中更详细的类变量,小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含3608字,纯文字阅读大概需要6分钟。
内容图文
![Java最佳实践:子类中更详细的类变量](/upload/InfoBanner/zyjiaocheng/788/5c273e3fcd2c469eb58856ef4dbc1ec3.jpg)
我正在使用java为一些算法建模一个可绘制的平面图.
我的基本课程是:
public class Node {
private String label;
}
和
public class Edge {
private Node node0;
private Node node1;
}
这对算法非常有用.为了绘制图形,我扩展了具有位置的节点类:
public class GraphicalNode extends Node {
private int x;
private int y;
}
我的问题是可绘边的类.我想写这样的东西:
public class GraphicalEdge extends Edge {
private GraphicalNode node0;
private GraphicalNode node1;
}
但我以前从未见过这样的设计.最重要的是,编译器需要一个构造函数public GraphicalNode(Node node0,Node node1)作为超类.
有没有人有想法实现这一点?
解决方法:
也许我在这里误解了一些东西 – 暗示将显示 – 但……
这听起来像是使用Covariance的教科书示例.
当您有一个具有Node getNode()方法的类Edge时,您可以在扩展Edge的类中为此方法定义更具体的返回类型.例如:
class Node {}
class Edge {
Node getNode();
}
class GraphicalNode extends Node {}
class GraphicalEdge extends Edge {
// This really overrides the method, with a more specific return type!
@Override
GraphicalNode getNode();
}
或者,使用您提供的类,使用您提到的构造函数扩展,以及一些getter,组装成MCVE:
public class WhatIsCovariance
{
public static void main(String[] args)
{
Node n0 = new Node();
Node n1 = new Node();
Edge e0 = new Edge(n0, n1);
Node n = e0.getNode0(); // Works
GraphicalNode gn0 = new GraphicalNode();
GraphicalNode gn1 = new GraphicalNode();
GraphicalEdge ge0 = new GraphicalEdge(gn0, gn1);
GraphicalNode gn = ge0.getNode0(); // Works
}
}
class Node
{
private String label;
}
class Edge
{
private Node node0;
private Node node1;
Edge(Node node0, Node node1)
{
this.node0 = node0;
this.node1 = node1;
}
public Node getNode0()
{
return node0;
}
public Node getNode1()
{
return node1;
}
}
class GraphicalNode extends Node
{
private int x;
private int y;
}
class GraphicalEdge extends Edge
{
private GraphicalNode node0;
private GraphicalNode node1;
GraphicalEdge(GraphicalNode node0, GraphicalNode node1)
{
super(node0, node1);
this.node0 = node0;
this.node1 = node1;
}
@Override
public GraphicalNode getNode0()
{
return node0;
}
@Override
public GraphicalNode getNode1()
{
return node1;
}
}
这里的关键点是:当您有Edge类型的引用时,您只能从中获取一个Node(即使引用引用的对象实际上是GraphicalEdge).仅当引用的类型是GraphicalEdge时,您还可以从中获取GraphicalNode.
这在许多情况下都很方便,并且通常允许清晰地分离关注点:当方法只需要对Edge和Node对象进行操作,并且对它们的图形表示不感兴趣时??,您可以使用基类编写其签名:
void computeSomething(Edge edge) {
Node n0 = edge.getNode();
Node n1 = edge.getNode();
...
}
void run() {
GraphicialEdge e = new GraphicalEdge(...);
computeSomething(e);
}
当一个方法确实需要图形表示时,你会让它采用图形边缘:
void drawSomething(GraphicalEdge edge) {
GraphicalNode n0 = edge.getNode();
GraphicalNode n1 = edge.getNode();
...
}
void run() {
GraphicialEdge e = new GraphicalEdge(...);
computeSomething(e); // Works
drawSomething(e); // Works as well
Edge edge = e;
drawSomething(edge); // Does not work. A GraphicalEdge is required.
}
一个侧面说明,或者可能是关键点,考虑到你的问题特别关注……
类变量:
使用您在那里绘制的当前设计,每个GraphicalEdge将存储其节点两次 – 一次作为GraphicalNode,一次作为一个简单的节点.例如,通过将事物定义为接口,可以避免这种情况:
interface Node {}
interface Edge {
Node getNode();
}
interface GraphicalNode extends Node {}
interface GraphicalEdge extends Edge {
@Override
GraphicalNode getNode();
}
class DefaultEdge implements GraphicalEdge { ... }
使用泛型,如wero suggested in his answer,可以添加更多自由度,并且考虑到更多节点类型,可能是更清晰和更灵活的设计.例如,您可能稍后想要引入类似于ColoredGraphicalNode的东西,这可以很好地被泛型类型参数覆盖.但它的代价是更隐秘的方法签名:以通用形式编写方法,允许“路由”所需的类型信息可能会变得有点麻烦,这取决于你想要去那里多远.
内容总结
以上是互联网集市为您收集整理的Java最佳实践:子类中更详细的类变量全部内容,希望文章能够帮你解决Java最佳实践:子类中更详细的类变量所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。