Как реализовать метод при наследовании класса и интерфейсв

Есть абстрактный класс A и интерфейс B. Есть классы которые наследуются только от класса A и классы которые наследуются от класса A и иплиментирует интерфейс B. Есть метод в котором выполняются методы из класса A и интерфейса B. Как реализовать метод? У меня есть несколько вариантов но у них есть свои минусы:

1 вариант

public void run(A a, B b) {
  //код
}

Минус в том что требуется указать два раза один и тот-же класс

2 вариант

public void run(A a){
   B b = (B) a
   //код
}

Минус в том что в этот метод можно положить любого наследника класса A из-за этого можно получить исключение ClassCastException

3 вариант

Класс

public class C extends A implements B {}

Метод

public void run(C c){
  //код
} 

Минус в том что нужно создавать пустой класс


Ответы (2 шт):

Автор решения: Швеев Алексей

Если класс и интерфейс почти никак не связанны друг с другом, но вдруг вам всё же понадобилась именно их комбинация (что происходит довольно редко), то вы можете использовать генерики:

class A {
    void foo() {}
}

interface B {
    void bar();
}

class Something extends A implements B {
    public void bar() {}
}

class Main
{
    public static void main (String[] args) throws java.lang.Exception
    {
        Method(new Something());
    }
    
    public static <T extends A & B> void Method(T idk) {
        idk.foo();
        idk.bar();
    }
}

НО!

В большинстве случаев лучше всё же создать общий абстрактный класс:

abstract class C extends A implements B {}
→ Ссылка
Автор решения: Roman C

Кажется я понял, что вам требуется реализовать четвертый вариант

Сначала определим класс A следующим образом:

public abstract class A implements B {}

тогда метод можно определить как

public void run(B b) {
  //код
  A a;
  if (b instanceof A) {
    a = b;
  } 
}

То есть объект может быть трёх типов:

  1. Подклассы A
  2. Классы, имплементирующие B
  3. Подклассы A, имплементирующие B

Все они подходят для метода, за исключением: все классы должны имплементировать B, поэтому имплементацию B нужно добавить в A по умолчанию, в случае чего, её можно будет переопределить в подклассах.

→ Ссылка