对问题标题表示道歉,我无法轻易将其写入文字.
我在一些代码中遇到过这个问题:
public class MyClass implements Message<MyClass> {...}
Run Code Online (Sandbox Code Playgroud)
我理解它的作用,但我以前从未见过以这种方式宣布的类.
我看到的缺点是现在MyClass是一个消息,需要包含与其主要目的无关的已实现方法.
我看到的一个优点(除了它减少了我本来需要编写的其他类的数量)是因为对于类似的事情Comparable,MyClass会知道如何将自己与其他实例进行比较,这反过来会使代码更简洁.
这是好习惯吗?有没有经验法则?
这或多或少是Java中唯一一种具有引用实现类本身的方法的接口的方法.因此,例如,您可以编写二叉树节点接口:
interface TreeNode<N extends TreeNode<N>> {
N getLeftChild();
N getRightChild();
void setLeftChild(N node);
void setRightChild(N node);
}
Run Code Online (Sandbox Code Playgroud)
然后你有类似的课程
class TreeNodeWithInt extends TreeNode<TreeNodeWithInt> {
int value;
TreeNodeWithInt leftChild;
TreeNodeWithInt rightChild;
public TreeNodeWithInt getLeftChild() { return leftChild; }
public void setLeftChild(TreeNodeWithInt newLeft) { leftChild = newLeft; }
...
}
Run Code Online (Sandbox Code Playgroud)
如果我们没有Ntype参数,你将被迫编写不安全的代码
class TreeNodeWithInt extends TreeNode {
int value;
TreeNodeWithInt leftChild;
TreeNodeWithInt rightChild;
public void setLeftChild(TreeNode node) {
// note the dangerous cast!
leftChild = (TreeNodeWithInt) node;
}
}
Run Code Online (Sandbox Code Playgroud)
这里的关键问题是,当接口描述输入和返回类型的方法时,不允许接口引用实现接口的类的类型.因此,您需要包含"自我"泛型类型参数.这是代码中相对常见的习惯用法,它广泛使用泛型.
正如您所正确识别的那样,它经常被Comparable特别使用,因为您应该只能将对象与相同类型的其他对象进行比较.实际上,Collections.sort指定采用List<T>where T extends Comparable<? super T>,这意味着至少T可以与其他类型的值相比,但也可能是其他值.T
(最后,正如你所料 - 因为它是实现这种行为的唯一方法,它不是"好"或"坏"的实践.也就是说,该技术的目标是避免编写没有警告而编译但可以结束的方法投掷ClassCastException,这本身就是一种很好的做法.)