2014-10-07 93 views
1

我有一些抽象的超类和一些实现的方法。子类中的隐藏方法

是否有可能隐藏在子类从这个超类继承自该超类的方法?我不想在某些子类中的超类中看到某些方法。最后但并非最不重要的是,是否可以更改超类中具有相同名称的子类中某个方法的参数个数?

假设我们在超类中有一个方法public void test(int a, int b),但现在我想要调用超类功能的子类中的方法public void test(int a),并且超类中的方法不再可见。

+0

我是否设法回答您的问题?还是有些不清楚? – aioobe 2014-10-13 15:02:59

回答

4

是否有可能在从这个超类继承的子类中隐藏这个超类的方法?

如果您的方法在超类私有的,它不会在子类中可见(或任何其他人)。

如果您需要在基类中的方法,但是是公开的,不存在由例如与私有实现覆盖它掩藏它在子类中的方法。 (您不能“降低可见性”,即从例如公共或受保护到子类中的私有。)

最好的解决方法是重写该方法并抛出运行时异常,如UnsupportedOperationException

是有可能改变的参数的个数为具有超类中相同名称的子类的方法?

不,您不能更改签名。您可以创建另一个具有相同名称和不同数量参数的方法,但这将是一个不同的(重载)方法,并且基类中的方法仍然可见。

+0

解决方法是在超类中创建方法'protected',然后有两个实现。一个只是让方法'公开'(即授予访问父API),而另一个创建调用父API的新方法。第二种类型隐藏了父API(但子类仍然可以看到它们)。 – 2014-10-07 13:11:11

+1

第二个问题的答案是正确的,但我认为它的措辞是误导性的。通过更改参数的数量和类型来重载方法名称是完全可以的。此外,重载的方法名称的访问限定符没有限制(只要签名不匹配另一个继承的方法)。但是,超类方法仍然可见。 – 2014-10-07 13:14:08

+0

这不是*改变*参数的数量,即*添加*另一个方法与不同数量的参数。 – aioobe 2014-10-07 13:19:02

1

你不能完全隐藏从超类的方法,它总是可以调用,例如,

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) { ; } 
} 
0

Java不支持能见度降低。

有一种方法可以做这样的事情,但它是复杂的:

  1. 您需要创建父类型的接口。这个接口不需要有方法。
  2. 您可以创建另一个新类型Delegate,该类型实现方法public void test(int a, int b)
  3. 您可以删除当前父类型。
  4. 您创建两个实现该接口的新类型。一个代理test(a,b)Delegate,另一个创建一个新方法test(a),最终使用一个Delegate实例。

所以实现旧代码的类型永远不会被外部世界看到(它可能是一个包私有类)。

+0

当然,那么新类型的对象将不再是基类的实例。 – 2014-10-07 13:33:50

+0

这就是为什么新类型实现相同的接口。正如我所说,这不是很好,很清楚,等等。 – 2014-10-07 13:35:30

+0

对不起 - 我在评论中不清楚。原始基类具有某些方法,而新类型没有,因此在客户端代码被编写为使用基类的这些方法的情况下,它们不可用。您提出了一个与OP似乎面临的问题不同的好架构。 – 2014-10-07 13:38:54

1

不,您不能在子项中隐藏公共方法,例如将方法隐藏在那里。

原因是有一个子类的实例,你可能总是把它转换到基类,并在那里调用方法。

所以这种行为是合乎逻辑的。要么重新设计类层次结构,要么创建一个新类,如果这成为一个太丑陋的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); 
} 

重载的方法是可行的:同一个名字,不同的参数类型。