Java 在实现接口时扩展包含的类型

Java 在实现接口时扩展包含的类型,java,inheritance,interface,Java,Inheritance,Interface,我创建了两个Java接口,Tree和BinarySearchTree,其中第二个接口扩展了第一个接口。我有一个BinarySearchTree的实现,名为LinkedBinarySearchTree。以下代码在编译时显然会出现问题: Tree<Object> a = new LinkedBinarySearchTree<Object>(); Tree a=newlinkedbinarysearchtree(); 由于LinkedBinarySearchTree实现了一

我创建了两个Java接口,
Tree
BinarySearchTree
,其中第二个接口扩展了第一个接口。我有一个
BinarySearchTree
的实现,名为
LinkedBinarySearchTree
。以下代码在编译时显然会出现问题:

Tree<Object> a = new LinkedBinarySearchTree<Object>();
Tree a=newlinkedbinarysearchtree();
由于
LinkedBinarySearchTree
实现了一个接口,该接口已将
T
指定为
Compariable
类型,并且
对象
不是
Compariable
。我完全理解这一点,这对我的实现来说并不构成问题


我想了解的是,这种方法在实践中是否危险。我无法想象数据类型从
Tree
缩小到
BinarySearchTree
会给我带来运行时错误(
ClassCastException
),但我希望与知识更丰富的人确认这一点。本质上,在扩展接口时“缩小”接口所持有的类型是否被视为不好的做法?如果是,原因是什么?

这似乎根本不是不好的做法。是否获得
ClassCastException
取决于您尝试做什么,而不是实现方法

“缩小范围”的一个常见情况是,当一个人想要专门化从公共基础派生的特定实现的类型时。例如,要实现某些计算器,每次使用不同的返回类型:

public interface Calculator<T> {
    public Number calculate(T... arguments);
}

public interface NumberCalculator<T extends Number> extends Calculator<T> {
    @Override
    public T calculate(T... arguments);
}

public interface IntegerNumberCalculator extends NumberCalculator<Integer> {
    @Override
    public Integer calculate(Integer... arguments);
}

public interface FloatNumberCalculator extends NumberCalculator<Float> {
    @Override
    public Float calculate(Float... arguments);
}
公共接口计算器{
公共数计算(T…参数);
}
公共接口数字计算器扩展计算器{
@凌驾
公共T计算(T…参数);
}
公共接口整数数字计算器扩展数字计算器{
@凌驾
公共整数计算(整数…参数);
}
公共接口FloatNumberCalculator扩展了NumberCalculator{
@凌驾
公共浮点计算(浮点…参数);
}

上面的参数可以指定为不同于
,而返回类型可以继续为每个子类设置为
,因此,与必须始终返回
数字
对象相比,它提供了更好的类型一致性。

事实上恰恰相反,这实际上是一种很好的做法


请记住,使用泛型是一种通过在编译时捕获尽可能多的错误来避免编码错误的技术。通过加强
BinarSearchTree
接口的特殊性,实际上会使人们更难意外地滥用它。不仅如此,他们的错误还会在编译时被发现。

不,这不是一个坏习惯。您可以通过不缩小类型范围,并像TreeSet那样请求一个比较器作为参数,使BST更通用。