Możesz jak najbardziej zrobić też po zwykłej klasie lub po klasie implementującej jakiś wspólny interfejs. Jednak ponieważ obiekty dziedziczące po klasach Swinga już mają swojego przodka, to musisz skorzystać z klas wewnętrznych, które będą dziedziczyć po tej klasie ze wspólnym kodem. Na przykład coś w tym stylu:
abstract class WspólnyKod
{
private Component c;
public WspólnyKod(Component c) { this.c = c; }
protected Component get() { return c; }
protected void metoda1()
{
System.out.println("Komponent graficzny:" + c.getName());
}
protected Window metoda2(Window w)
{
System.out.println("Okno top-level: " + w.getName());
System.out.println("Inny obiekt: " + metoda3());
return w;
}
abstract protected JComponent metoda3();
}
class InnyWspólnyKod
{
//...
}
interface WspólnyInterfejs
{
//...
class KomplikacjaDoKwadratu
{
//...
}
}
class MyJPanel extends JPanel
{
private class Impl extends WspólnyKod
{
protected class Impl2level
extends InnyWspólnyKod
implements WspólnyInterfejs
{
public Impl2level() {}
//...
}
private Impl2level y = new Impl2level();
private Impl(JComponent c) { super(c); }
@Override protected JComponent metoda3()
{
//...
System.out.println("Adres klasy podwójnie wewnętrznej: " + y);
return (JComponent)get();
}
}
private Impl x = new Impl(this);
private JFrame f;
public MyJPanel(JFrame f) { this.f = f; }
//...
public void i()
{
System.out.println("Realne dziedziczenie po 2 klasach");
x.metoda1();
System.out.println("Obiekt okna top-level: "
+ x.metoda2(f).getName());
System.out.println("Jakieś okno: " + x.metoda3());
}
Trochę wydaje się to skomplikowane, ale sprowadza się do tego, że jak nie możesz dziedziczyć po jakiejś klasie bo dziedziczysz już po innej, to niech dziedziczy Twoja klasa wewnętrzna, z którą możesz zrobić wszystko. Klasa wewnętrzna (tu prywatna) ma dostęp zarówno do kodu po którym dziedziczy jak i do kodu klasy ją obejmującej dzięki niejawnie używanemu polu MyJPanel.this, którym poprzedzone są wszelkie dostępy do pól i metod tej klasy.
Realizacja klas wewnętrznych jest na poziomie generowanego kodu bardzo podobna do dziedziczenia wielobazowego w C++. Dziedziczenie z użyciem klas wewnętrznych ma tak naprawdę jeszcze większe możliwości niż każda postać dziedziczenia wielobazowego z C++. A to dlatego, że nie tylko mamy nad tymi klasami jawną i całkowita kontrolę oraz dlatego, że klasy wewnętrzne mogą dziedziczyć po klasach, które mają niby wielobazowe dziedziczenie - ale mogą mieć również cały garnitur swoich klas wewnętrznych połączonych na najróżniejsze sposoby. Ba, nawet klasy abstrakcyjne i interfejsy mogą mieć swoje klasy wewnętrzne, a więc interfejs, który nie może mieć własnego kodu może realnie dziedziczyć wielobazowo po realnym kodzie. A właściwie nie tyle interfejs ile klasa, która go zaimplementuje.