简体   繁体   中英

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.

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 .

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.

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.

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)
  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.

So the type which implements the old code is never visible to the outside world (it could be a package private class).

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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