Java: расширение класса и реализация интерфейса с одинаковым методом - PullRequest
23 голосов
/ 14 октября 2011

Вероятно, следующее не может быть сделано (я получаю ошибку компиляции: «Унаследованный метод A.doSomthing (int) не может скрыть публичный абстрактный метод в B»):

public class A {
    int doSomthing(int x) {
        return x;
    }
}

public interface B {
    int doSomthing(int x);
}

public class C extends A implements B {

    //trying to override doSomthing...

    int doSomthing(int x) {
        return doSomthingElse(x);
    }
}

Предполагается, что яразрешено изменять ни A, ни B, мой вопрос: могу ли я как-то определить C таким образом, чтобы он наследовал от A и B (предположим, что для некоторой структуры требуется, чтобы C был одновременно экземпляром A и B).

Или, если нет, как бы вы справились с этим?

Спасибо!

Ответы [ 4 ]

27 голосов
/ 14 октября 2011

сделать метод общедоступным

public class C extends A implements B {

    //trying to override doSomthing...

    public int myMethod(int x) {
        return doSomthingElse(x);
    }
}

методы интерфейса всегда public

или просто использовать композицию вместо наследования

8 голосов
/ 14 октября 2011

Метод doSomethis() равен пакетный в классе A:

public class A {
    int doSomthing(int x) { // this is package-private
        return x;
    }
}

Но это public в интерфейсе B:

public interface B {
    int doSomthing(int x); // this here is public by default
}

Компилятор принимает doSomething(), унаследованный C от A, который является package-private , в качестве реализации того, что в B, которое является public . Вот почему он жалуется -

"Унаследованный метод A.doSomthing (int) не может скрыть публичный абстрактный метод в B"

Потому что, хотя переопределяет метод, вы не можете сузить уровень доступа метода.

Решение простое, в классе C -

@Override
public int doSomthing(int x) {
    // ...
}
2 голосов
/ 14 октября 2011

Это связано с видимостью. Вы используете default (без модификатора) видимость в C для myMethod, но она должна быть public в соответствии с интерфейсом B.

Теперь вы можете подумать, что использовали видимость default для всех из них, поскольку ни в A, B, ни в C вы явно не выбрали один из public, private или protected. Однако интерфейс использует public независимо от того, указали ли вы это явно.

0 голосов
/ 14 октября 2011

Просто сделайте метод public при переопределении в C.

...