简体   繁体   English

隐藏子类中的方法

[英]Hiding methods in subclass

I have a abstract superclass with some implemented methods. 我有一个带有某些已实现方法的抽象超类。

Is it possible to hide methods from this superclass in an subclass inheriting from this superclass? 是否可以在继承自该超类的子类中隐藏该超类的方法? I don't want to have some methods visible from the superclass in some of the subclasses. 我不想从某些子类的超类中看到一些方法。 Last but not least, is it possible to change the number of arguments for a method in the subclass which has the same name in the superclass? 最后但并非最不重要的一点是,是否可以更改子类中与超类同名的方法的参数数量?

Let's say we have a method public void test(int a, int b) in the superclass but now I want a method public void test(int a) in the subclass which calls the superclass function and the method from the superclass not visible anymore. 假设我们在超类中有一个方法public void test(int a, int b) ,但现在我想要在子类中有一个方法public void test(int a) ,该方法调用超类函数,并且超类中的方法不再可见。

Is it possible to hide methods from this superclass in an subclass inheriting from this superclass? 是否可以在继承自该超类的子类中隐藏该超类的方法?

If you make the method private in the super class, it won't be visible in the subclass (or to any one else). 如果您在超类中将方法设为私有,则该方法在子类(或其他任何子类)中将不可见。

If you need the method in the base class to be public however, there is no way of hiding it in the subclass by for instance overriding it with a private implementation. 但是,如果您需要基类中的方法是公共的,则无法将其隐藏在子类中,例如通过私有实现覆盖它。 (You can't "reduce visibility", ie go from for instance public or protected to private in a subclass.) (您不能“降低可见性”,即在子类中从“公开”或“受保护”变为“私有”。)

The best workaround is probably to override the method and throw for a runtime exception such as UnsupportedOperationException . 最好的解决方法可能是重写方法并抛出运行时异常,例如UnsupportedOperationException

is it possible to change the number of arguments for a method in the subclass which has the same name in the superclass? 是否可以更改子类中与超类同名的方法的参数数量?

No, you can't change the signature. 不,您不能更改签名。 You can create another method with the same name and a different number of arguments but this would be a different (overloaded) method and the method in the base class would still be visible. 您可以创建另一个具有相同名称和不同数量参数的方法,但这将是一个不同的(重载)方法,并且基类中的方法仍然可见。

You can't completely hide a method from superclass, it's always possible to call, eg 您无法从超类中完全隐藏方法,始终可以调用,例如

  MyBase o = new MyClass();
  o.test(1, 2);

However, you can override the method in a specific way: 但是,您可以通过特定方式覆盖该方法:

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

No you cannot hide a public method in a child, for instance by making the method private there. 不,您不能在子项中隐藏公共方法,例如,通过在子项中将方法设为私有。

The reason is that having an instance of the child class, you may always cast it to the base class, and call the method there. 原因是拥有子类的实例,您可能总是将其强制转换为基类,然后在其中调用方法。

So this behaviour is logical. 因此,这种行为是合乎逻辑的。 Either redesign the class hierarchy or create a new class if this is becoming a too ugly API. 重新设计类层次结构,或者如果新API变得过于丑陋,则创建一个新类。

You may however override the method and 但是,您可以覆盖该方法,

/**
 * 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);
}

Overloading a method is possible: same name, different parameter types. 可以重载方法:相同的名称,不同的参数类型。

Java doesn't support reducing visibility. Java不支持降低可见性。

There is a way to do something like this but it's complex: 有一种方法可以执行以下操作,但是很复杂:

  1. You need to create an interface for the parent type. 您需要为父类型创建一个接口。 This interface doesn't need to have methods. 该接口不需要方法。
  2. You create another, new type Delegate which implements the method public void test(int a, int b) 您创建另一个新的Delegate类型,它实现方法public void test(int a, int b)
  3. You delete the current parent type. 您删除当前的父类型。
  4. You create two new types which implement the interface. 您将创建两个实现接口的新类型。 One delegates the call test(a,b) to Delegate and the other one creates a new method test(a) which eventually uses a Delegate instance. 一个将调用test(a,b) DelegateDelegate ,另一个则创建一个新方法test(a) ,该方法最终使用Delegate实例。

So the type which implements the old code is never visible to the outside world (it could be a package private class). 因此,实现旧代码的类型永远不会对外界可见(它可以是程序包私有类)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM