Подтвердить что ты не робот

Реализация нескольких интерфейсов, имеющих тот же метод

Этот код работает отлично. Метод test() работает для обоих интерфейсов. Что именно происходит под капотом? И как эта функция полезна в практическом сценарии?

interface A
{
    void test();
}

interface B 
{
    void test();
}

class C implements A, B
{

    public void test() 
    {
        System.out.println("abc");
    }
}

   A a = new C();
   a.test();
   B b = new C();
   b.test();
4b9b3361

Ответ 1

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

Ваш класс C реализует этот метод, поэтому интерфейсы выполнили свою работу.

В основном ваш класс C говорит: "О, эй, мне нужно реализовать test() из-за интерфейса A", и вы его реализуете. Затем ваш класс C говорит: "О, эй, мне нужно снова реализовать test() из-за интерфейса B", и он видит, что уже реализован метод под названием test(), поэтому он удовлетворен.

Вы также можете найти дополнительную информацию здесь: JLS §8.4.8.4

Ответ 2

JLS §8.4.8.4 говорит,

Наследование методов с переопределяющими эквивалентными сигнатурами

Класс может наследовать несколько методов с переопределяющими эквивалентными сигнатурами (§8.4.2)
...
Может существовать несколько путей, по которым одно и то же объявление метода может быть унаследовано от интерфейса. Этот факт не вызывает затруднений и никогда сам по себе не приводит к ошибке времени компиляции.

Похоже, что обоснование заключается в том, что если класс имеет несколько деклараций с тем же именем и сигнатурой, поскольку класс может унаследовать их через несколько путей - реализация интерфейса, а также подкласс класса, реализующего этот интерфейс, например, - нет вред.

Ответ 3

Предположим, что у нас есть два интерфейса...

public interface StockBroker{
        //Give our client some investment strategies.
        public String adviseClient(Client c);
}

public interface Doctor{
  //Examine our client and give them some medical advice
        public String adviseClient(Client c);
}

И класс, реализующий оба интерфейса....

public class JackOfAllTrades implements StockBroker, Doctor{
   public String adviseClient(Client c){
   }
}

Хотя синтаксически корректно реализовать оба интерфейса с одним методом, вы не можете получить желаемое поведение. Например, биржевой брокер и врач обычно дают своим клиентам совершенно разные советы.

Кто-то, использующий объект, реализующий интерфейс Doctor, ожидает, что метод adviseClient() даст медицинскую консультацию. Но кто-то, использующий объект, реализующий интерфейс StockBroker, ожидает, что метод adviseClient() выдаст инвестиционные стратегии.

В этом случае объект JackOfAllTrades не знает, какой совет давать, потому что метод adviseClient() не имеет параметров, указывающих, какой интерфейс он должен реализовывать при вызове adviseClient().

Это недостаток в Java, потому что человек, проектирующий интерфейс Doctor, возможно, не знал, что кто-то другой разработает интерфейс StockBroker с той же сигнатурой метода.

Для всех, кто создает интерфейсы, его, вероятно, хорошая практика, чтобы сделать имена методов достаточно уникальными, чтобы столкновения имен были редкими.

Ответ 4

interface A
{
void test();
}

interface B 
{
void test();
}
class C implements A, B {

    public void test() 
    {
        System.out.println("common to all");
    }
    public A choose(A a){
        return new A(){
           public void test() {
                System.out.println("test of A");
           }
        };
    }
    public B choose(B b){
        return new B(){
           public void test() {
            System.out.println("test of B");
           }
        };
    }
}
class Demo {
   public static void main(String[] args) {
   C c =new C();

   A a = new C();
   B b = new B();

   a = c.choose(a);
   b = c.choose(b);

   a.test();
   b.test();
   }
}

Ответ 5

Не в синтаксисе, но если intent одного из methods не соблюдается, его контракт прерывается и код может считаться сломанным..

Используя вашу аналогию, если бы я обещал Майклу носить синюю рубашку вместо красной рубашки, и я не могу носить две рубашки, тогда мне придется сломать хотя бы одно обещание.

То же самое можно использовать для методов: если сохранение одного контракта означало бы размыкание другого, то это на самом деле плохая идея для implement как interfaces.

Изменить: контракт сломан, согласно Class C signature Он должен реализовать два метода, но в конечном итоге реализовать только один method и опустить другой.

Ссылка