Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7542025
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 30, 20262026-05-30T08:03:14+00:00 2026-05-30T08:03:14+00:00

Second attempt at this question (the initial code wasn’t enough to highlight the issue)

  • 0

Second attempt at this question (the initial code wasn’t enough to highlight the issue)

Here is the code that does not compile:

interface Player<R, G extends Game>
{
    R takeTurn(G game);
}

interface Game<P extends Player>
{
    void play(P player);
}

abstract class AbstractGame<R, P extends Player>
    implements Game<P>
{
    public final void play(final P player)
    {
        final R value;

        value = player.takeTurn(this);
        turnTaken(value);
    }

    protected abstract void turnTaken(R value);
}

public class XPlayer
    implements Player<Integer, XGame>
{
    @Override
    public Integer takeTurn(final XGame game)
    {
        return (42);
    }
}

public class XGame<P extends Player<Integer, XGame>>
    extends AbstractGame<Integer, XPlayer>
{
    @Override
    protected void turnTaken(final Integer value)
    {
        System.out.println("value = " + value);
    }
}

public class Main
{
    public static void main(final String[] argv) 
    {
        final XPlayer player;
        final XGame   game;

        player = new XPlayer();
        game   = new XGame();
        game.play(player);
    }
}

What I am running up against is trying to get the play method in the AbstractGame to compile. It seems that I have to run in circles with the Game and the Player adding generics to the extends/implements but for the life of me I cannot get it straight.

The play method has to be final in the AbstractGame class, and there is no way to do casting, and I don’t want to write another method like the turnTaken one to get it to work if I don’t have to.

EDIT: as requested here is the code that compiles, but needs the cast:

interface Player<R, P extends Player<R, P, G>, G extends Game<R, G, P>>
{
    R takeTurn(G game);
}

interface Game<R, G extends Game<R, G, P>, P extends Player<R, P, G>>
{
    void play(P player);
}

abstract class AbstractGame<R, G extends Game<R, G, P>, P extends Player<R, P, G>>
    implements Game<R, G, P>
{
    public final void play(final P player)
    {
        final R value;

        value = player.takeTurn((G)this);
        turnTaken(value);
    }

    protected abstract void turnTaken(R value);
}

class XPlayer
    implements Player<Integer, XPlayer, XGame>
{
    @Override
    public Integer takeTurn(final XGame game)
    {
        return (42);
    }
}

class XGame
    extends AbstractGame<Integer, XGame, XPlayer>
{
    @Override
    protected void turnTaken(final Integer value)
    {
        System.out.println("value = " + value);
    }
}

class Main
{
    public static void main(final String[] argv) 
    {
        final XPlayer player;
        final XGame   game;

        player = new XPlayer();
        game   = new XGame();
        game.play(player);
    }
}
  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-30T08:03:15+00:00Added an answer on May 30, 2026 at 8:03 am

    Mixing generics and raw types isn’t going to work. If you need these interfaces to reference each other, they also need to reference themselves:

    interface Player<R, P extends Player<R, P, G>, G extends Game<R, G, P>>
    {
        R takeTurn(G game);
    }
    
    interface Game<R, G extends Game<R, G, P>, P extends Player<R, P, G>>
    {
        void play(P player);
    }
    

    Although this is looking rather hairbrained, and I’m not sure why you need it.

    Edit:

    I was able to implement your AbstractGame based on the above:

    abstract class AbstractGame<R, P extends Player<R, P, AbstractGame<R, P>>>
        implements Game<R, AbstractGame<R, P>, P>
    {
        public final void play(final P player)
        {
            final R value;
    
            value = player.takeTurn(this);
            turnTaken(value);
        }
    
        protected abstract void turnTaken(R value);
    }
    

    However I couldn’t quite close the circuit with XGame and XPlayer:

    public class XGame
        extends AbstractGame<Integer, XPlayer> //compile error on XPlayer
    {
    
        protected void turnTaken(Integer value) { }
    }
    
    public class XPlayer
        implements Player<Integer, XPlayer, XGame> //compile error on XGame
    {
        @Override
        public Integer takeTurn(final XGame game)
        {
            return (42);
        }
    }
    

    The issue seems to be that each of the generic declarations of XGame and XPlayer needs the other to be correct. This is where your design is truly cyclical. If the compiler ‘assumed’ each was correct, it would in theory work. But it doesn’t.

    Edit 2:

    How about this:

    interface Game<R, G extends Game<R, G>>
    {
        void play(Player<R, G> player);
    }
    
    interface Player<R, G extends Game<R, G>>
    {
        R takeTurn(G game);
    }
    
    abstract class AbstractGame<R, G extends AbstractGame<R, G>>
        implements Game<R, G>
    {
        public final void play(final Player<R, G> player)
        {
            final R value;
    
            value = player.takeTurn(self());
            turnTaken(value);
        }
    
        protected abstract G self();
    
        protected abstract void turnTaken(R value);
    }
    
    public final class XGame extends AbstractGame<Integer, XGame>
    {
       protected XGame self() {
          return this;
       }
    
       protected void turnTaken(Integer value) { }
    }
    
    public class XPlayer implements Player<Integer, XGame>
    {
        @Override
        public Integer takeTurn(final XGame game)
        {
           return (42);
        }
    }
    

    The key here was declaring an abstract method self() in AbstractGame that returns an instance of type G. Extending classes must resolve the inherited type parameter with their own type, and implement self() to return this. This is only suitable for internal code, since an extending class could easily lie, for example:

    public class EvilGame extends AbstractGame<Integer, AnotherGame> { ... }
    

    See my answer here and this post for more details on this pattern.

    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

(Hope this doesn't get duplicated; second attempt at submitting this question) I'm working on
Sorry for the second newbie question, I'm a developer not a sysadmin so this
The second part of that question is key. If you are one of a
I've seen second one in another's code and I suppose this length comparison have
So this question is a sort of follow on from here ( how to
I have updated this question(found last question not clear, if you want to refer
This is a new attempt to pose a version of a question asked less
probably there are a lot of people who will smile reading this question... Here's
Background: I admit I did not attempt to benchmark this, but I'm curious... What
I'm learning how to traverse the DOM so this question is related to that.

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.