title: How to implement interfaces with homographic methods in Java?
body: <p>In English, a homograph pair is two words that have the same spelling but different meanings.</p>
  
  <p>In software engineering, a pair of homographic methods is two methods with the same name but different requirements. Let's see a contrived example to make the question as clear as possible:</p>
  
  <pre><code>interface I1 { 
      /** return 1 */ 
      int f()
  }
  interface I2 {
      /** return 2*/
      int f()
  }
  interface I12 extends I1, I2 {}
  </code></pre>
  
  <p>How can I implement <code>I12</code>? C# <a href="https://stackoverflow.com/questions/4103300/c-sharp-why-implement-interface-explicitly">has a way</a> to do this, but Java doesn't. So the only way around is a hack. How can it be done with reflection/bytecode tricks/etc <strong>most reliably</strong> (i.e it doesn't have to be a perfect solution, I just want the one that works the best)?</p>
  
  <hr>
  
  <p>Note that some existing closed source massive piece of legacy code which I cannot legally reverse engineer requires a parameter of type <code>I12</code> and delegates the <code>I12</code> both to code that has <code>I1</code> as a parameter, and code that has <code>I2</code> as a parameter. So basically I need to make an instance of <code>I12</code> that knows when it should act as <code>I1</code> and when it should act as <code>I2</code>, which I believe can be done by <a href="https://stackoverflow.com/questions/2737285/is-there-a-way-to-obtain-the-bytecode-for-a-class-at-runtime">looking at the bytecode at runtime</a> of the immediate caller. We can assume that no reflection is used by the callers, because this is straightforward code. The problem is that the author of <code>I12</code> didn't expect that Java merges <code>f</code> from both interfaces, so now I have to come up with the best hack around the problem. Nothing calls <code>I12.f</code> (obviously if the author wrote some code that actually calls <code>I12.f</code>, he would have noticed the problem before selling it).</p>
  
  <p>Note that I'm actually looking for an answer to this question, not how to restructure the code that I can't change. I'm looking for the best heuristic possible or an exact solution if one exists. See Gray's answer for a valid example (I'm sure there are more robust solutions).</p>
  
  <hr>
  
  <p><a href="https://stackoverflow.com/questions/15795058/triads-not-showing-up-to-fight-java-set-missing-an-item">Here</a> is a concrete example of how the problem of homographic methods within two interfaces can happen. And here is another concrete example:</p>
  
  <p>I have the following 6 simple classes/interfaces. It resembles a business around a theater and the artists who perform in it. For simplicity and to be specific, let's assume they are all created by different people.</p>
  
  <p><code>Set</code> represents a set, as in set theory:</p>
  
  <pre><code>interface Set {
      /** Complements this set,
          i.e: all elements in the set are removed,
          and all other elements in the universe are added. */
      public void complement();
      /** Remove an arbitrary element from the set */
      public void remove();
      public boolean empty();
  }
  </code></pre>
  
  <p><code>HRDepartment</code> uses <code>Set</code> to represent employees. It uses a sophisticated process to decode which employees to hire/fire:</p>
  
  <pre><code>import java.util.Random;
  class HRDepartment {
      private Random random = new Random();
      private Set employees;
  
      public HRDepartment(Set employees) {
          this.employees = employees;
      }
  
      public void doHiringAndLayingoffProcess() {
          if (random.nextBoolean())
              employees.complement();
          else
              employees.remove();
          if (employees.empty())
              employees.complement();
      }
  }
  </code></pre>
  
  <p>The universe of a <code>Set</code> of employees would probably be the employees who have applied to the employer. So when <code>complement</code> is called on that set, all the existing employees are fired, and all the other ones that applied previously are hired.</p>
  
  <p><code>Artist</code> represents an artist, such as a musician or an actor. An artist has an ego. This ego can increase when others compliment him:</p>
  
  <pre><code>interface Artist {
      /** Complements the artist. Increases ego. */
      public void complement();
      public int getEgo();
  }
  </code></pre>
  
  <p><code>Theater</code> makes an <code>Artist</code> perform, which possibly causes the <code>Artist</code> to be complemented. The theater's audience can judge the artist between performances. The higher the ego of the performer, the more likely the audience will like the <code>Artist</code>, but if the ego goes beyond a certain point, the artist will be viewed negatively by the audience:</p>
  
  <pre><code>import java.util.Random;
  public class Theater {
      private Artist artist;
      private Random random = new Random();
  
      public Theater(Artist artist) {
          this.artist = artist;
      }
      public void perform() {
          if (random.nextBoolean())
              artist.complement();
      }
      public boolean judge() {
          int ego = artist.getEgo();
          if (ego &gt; 10)
              return false;
          return (ego - random.nextInt(15) &gt; 0);
      }
  }
  </code></pre>
  
  <p><code>ArtistSet</code> is simply an <code>Artist</code> and a <code>Set</code>:</p>
  
  <pre><code>/** A set of associated artists, e.g: a band. */
  interface ArtistSet extends Set, Artist {
  }
  </code></pre>
  
  <p><code>TheaterManager</code> runs the show. If the theater's audience judges the artist negatively, the theater talks to the HR department, which will in turn fire artists, hire new ones, etc:</p>
  
  <pre><code>class TheaterManager {
      private Theater theater;
      private HRDepartment hr;
  
      public TheaterManager(ArtistSet artists) {
          this.theater = new Theater(artists);
          this.hr = new HRDepartment(artists);
      }
  
      public void runShow() {
          theater.perform();
          if (!theater.judge()) {
              hr.doHiringAndLayingoffProcess();
          }
      }
  }
  </code></pre>
  
  <p>The problem becomes clear once you try to implement an <code>ArtistSet</code>: both superinterfaces specify that <code>complement</code> should do something else, so you have to implement two <code>complement</code> methods with the same signature within the same class, somehow. <code>Artist.complement</code> is a homograph of <code>Set.complement</code>.</p>