ytterrr
ytterrr

Reputation: 3246

Java Self-referential generics with two types

Let’s say we have an abstract class like this one:

abstract class Table<T extends Table<T, P>, P extends Menu<P>> { }

How to correctly declare its implementation?

public class TableImpl extends Table< **SOMETHING GOES HERE** > { }

I tried some variants and the only workaround I’ve found was to create additional classes:

public abstract class AbstractMenu extends Menu<AbstractMenu> { }
public abstract class AbstractTable extends Table<AbstractTable, AbstractMenu> { }

Then it’s possible to declare TableImpl like this:

public class TableImpl extends AbstractTable { }

EDIT 1

Based on Ingo's answer it now looks like this:

public class MenuAndTableTest {

    public abstract class Table<X extends Table<X>> {

        public abstract <M extends Menu> M getParent();

        public abstract X getThis();
    }

    public abstract class Menu<T extends Menu<T>> {

    }

    public class MenuImpl extends Menu<MenuImpl> {

    }

    public class TableImpl<M extends Menu> extends Table<TableImpl<M>> {

        M parent;

        public TableImpl(M parent) {
            this.parent = parent;
        }

        @Override
        public TableImpl getThis() {
            return this;
        }

        @Override
        public M getParent() {
            return parent;
        }

    }

    @Test
    public void Test() {
        // given
        MenuImpl menuImpl = new MenuImpl();
        // when
        TableImpl<MenuImpl> tableImpl = new TableImpl<>(menuImpl);
        // then
        assertEquals(tableImpl, tableImpl.getThis());
        assertEquals(menuImpl, tableImpl.getParent());
    }
}

But now some extra logic comes to Table implementations - not exactly what I wanted.

Upvotes: 1

Views: 127

Answers (1)

Ingo
Ingo

Reputation: 36349

If you want a table that can conatin a table that contains menus, why don't you declare it as

class Table<X>

and instantiate with

Table<Table<Menu>>

Upvotes: 3

Related Questions