假设给定一个类层次结构
class Region{};
class Shape extends Region{};
class Triangle extends Shape{};
class Circle extends Shape{};
有没有办法定义仅接受Shape
或Triangle
但不接受Circle
的方法?
我可以执行运行时类型检查并抛出异常,但编译时类型检查会好得多。
(澄清:通过写“给定一个类层次结构”,我的意思是它不能改变)。
答案 0 :(得分:3)
你不能在编译时进行这样的检查(给定你当前的类层次结构),因为Circle
是Shape
,所以任何接受Shape
参数的方法都会接受Circle
参数。
您必须更改类层次结构或引入一些新界面。
一些选项:
引入一个Shape
的子类,代表所有不是Circle
的形状(让我们称之为NotCircleShape
,但你应该想到一个积极的描述所有不是Circle
的形状的共同点是什么,让你的方法接受该子类的参数。
介绍除Shape
之外的所有Circle
实现的接口,并让您的方法接受该接口的参数。
答案 1 :(得分:1)
如果您当然愿意重新设计 class
系统,那么层次结构设计的变化可以帮助您实现这一目标。
解决方案1 :自定义interface
Triangle
以及Shape
除Circle
以外的所有其他子类实现自定义interface
。鉴于你的用例,我们称之为
public interface NonEllipticalShape {}
然后将方法签名更改为
public <T extends Shape & NonEllipticalShape > void method(T t) {
...
}
这个会阻止类型Shape
作为参数传递,但看起来Shape
不应该是可实例化的类型。
你有,像
class Circle extends Shape {}
class Triangle extends Shape implements NonEllipticalShape {}
class Rectangle extends Shape implements NonEllipticalShape {}
解决方案2 :具体工厂方法
关注this trick并仅将实用程序类的实例提供给特定的子类型。
class MethodClass<T extends Region> {
private MethodClass() {} // private constructor
public static <T extends Triangle> MethodClass<T> instance(T c) {
return new MethodClass<T>();
}
public static <T extends Rectangle> MethodClass<T> instance(T c) {
return new MethodClass<T>();
}
public void method(T t) {
}
}
只允许通过工厂方法允许的类进入MethodClass
个实例。因此,它的方法仅保留给特定类型T
,但这需要每个形状的工厂方法。
此处也不应接受T extends Shape
类型,或Circle
将成为有效参数。