子类中的隐藏方法
我有一些抽象的超类和一些实现的方法。子类中的隐藏方法
是否有可能隐藏在子类从这个超类继承自该超类的方法?我不想在某些子类中的超类中看到某些方法。最后但并非最不重要的是,是否可以更改超类中具有相同名称的子类中某个方法的参数个数?
假设我们在超类中有一个方法public void test(int a, int b)
,但现在我想要调用超类功能的子类中的方法public void test(int a)
,并且超类中的方法不再可见。
是否有可能在从这个超类继承的子类中隐藏这个超类的方法?
如果您的方法在超类私有的,它不会在子类中可见(或任何其他人)。
如果您需要在基类中的方法,但是是公开的,不存在由例如与私有实现覆盖它掩藏它在子类中的方法。 (您不能“降低可见性”,即从例如公共或受保护到子类中的私有。)
最好的解决方法是重写该方法并抛出运行时异常,如UnsupportedOperationException
。
是有可能改变的参数的个数为具有超类中相同名称的子类的方法?
不,您不能更改签名。您可以创建另一个具有相同名称和不同数量参数的方法,但这将是一个不同的(重载)方法,并且基类中的方法仍然可见。
解决方法是在超类中创建方法'protected',然后有两个实现。一个只是让方法'公开'(即授予访问父API),而另一个创建调用父API的新方法。第二种类型隐藏了父API(但子类仍然可以看到它们)。 – 2014-10-07 13:11:11
第二个问题的答案是正确的,但我认为它的措辞是误导性的。通过更改参数的数量和类型来重载方法名称是完全可以的。此外,重载的方法名称的访问限定符没有限制(只要签名不匹配另一个继承的方法)。但是,超类方法仍然可见。 – 2014-10-07 13:14:08
这不是*改变*参数的数量,即*添加*另一个方法与不同数量的参数。 – aioobe 2014-10-07 13:19:02
你不能完全隐藏从超类的方法,它总是可以调用,例如,
MyBase o = new MyClass();
o.test(1, 2);
但是,你可以在一个特定的方式覆盖的方法:
class MySuper {
public void test(int a, int b) {; }
}
class MyClass extends MySuper {
@Deprecated
@Override
public void test(int a, int b) {
throw new UnsupportedOperationException("Do not call this method, call test(int a) instead!");
}
public void test(int a) { ; }
}
Java不支持能见度降低。
有一种方法可以做这样的事情,但它是复杂的:
- 您需要创建父类型的接口。这个接口不需要有方法。
- 您可以创建另一个新类型
Delegate
,该类型实现方法public void test(int a, int b)
- 您可以删除当前父类型。
- 您创建两个实现该接口的新类型。一个代理
test(a,b)
到Delegate
,另一个创建一个新方法test(a)
,最终使用一个Delegate
实例。
所以实现旧代码的类型永远不会被外部世界看到(它可能是一个包私有类)。
当然,那么新类型的对象将不再是基类的实例。 – 2014-10-07 13:33:50
这就是为什么新类型实现相同的接口。正如我所说,这不是很好,很清楚,等等。 – 2014-10-07 13:35:30
对不起 - 我在评论中不清楚。原始基类具有某些方法,而新类型没有,因此在客户端代码被编写为使用基类的这些方法的情况下,它们不可用。您提出了一个与OP似乎面临的问题不同的好架构。 – 2014-10-07 13:38:54
不,您不能在子项中隐藏公共方法,例如将方法隐藏在那里。
原因是有一个子类的实例,你可能总是把它转换到基类,并在那里调用方法。
所以这种行为是合乎逻辑的。要么重新设计类层次结构,要么创建一个新类,如果这成为一个太丑陋的API。
但是你可以覆盖的方法和
/**
* Use <code>test(a)</code> instead.
* @param a.
* @param b.
*/
@Deprecated
@Override
public void test(int a, int b) {
throw new UnsupportedOperationException("Use test(int) instead.");
}
public void test(int a) { // Overloaded method
int b = ...;
super.test(a, b);
}
重载的方法是可行的:同一个名字,不同的参数类型。
我是否设法回答您的问题?还是有些不清楚? – aioobe 2014-10-13 15:02:59