0

I have a problem with management classes and interfaces in Java. I have a interface Superhero and other interface called Human. Then I have various classe of Human type for example PeterParker. At the end I have a Interface called HumanAndSuper that has this method:

public interface HumanAndSuper{

      public Superhero fromHumanToSuperhero();
      public Human fromSuperheroToHuman();


    }
    public interface SuperHero{

      public void attacks();

   }

When I create a Human object,for example PeterParker,in this class I have a private nested Superhero class. For example:

     public class PeterParker implements Human,HumanAndSuper{
         //Constructors

          public Superhero fromHumanToSuperhero(){
              //the human turns into superhero associated
              return new Spiderman();
          }
          public Human fromSuperheroToHuman(){
          //the superhero becomes a human
              return this;
          }
public void speaks(){//It's a example
    //Implementation
}

        private class Spiderman extends PeterParker implements SuperHero{


            public void attacks(){
               //Implementation
            }
         }

        }

In practice the implementation of the superhero relative to human is internal to the same class of the human. what I would like is to be able to instantiate a human with the same variable can pass from human to superhero and vice versa. For example:

PeterParker peter=new PeterParker();//Human
peter.speaks();
peter=peter.fromHumanToSuperhero();//peter becomes spiderman
peter.attacks();//method in Spiderman class
peter=peter.fromSuperheroToHuman();//spiderman becomes Human 

how can I achieve such a thing?

  • `PeterParker` isn't a `SuperHero`, so the assignment `peter = peter.fromHumanToSuperhero();` won't work. It's unclear what you're trying to achieve here. Can you elaborate? – Thorn G May 10 '14 at 19:43
  • You mean, how to allow a different set of methods in different contexts? That's only possible in Java by casting, or by throwing an exception if a method is not allowed in a certain context (e.g. ``IllegalStateException``). (and probably some more...) – Andy May 10 '14 at 19:43
  • You should read about Strategy pattern. Like this [How does the Strategy Pattern work?][1] [1]: http://stackoverflow.com/questions/91932/how-does-the-strategy-pattern-work – shadrus May 10 '14 at 19:47

2 Answers2

2

As far as I understand you're trying to create an instance of a class, and then make that instance become an instance of another class. That's not possible in Java.

However, if you want to change the behaviour of an instance dynamically, I suggest you to look at the Decorator pattern.

In object-oriented programming, the decorator pattern (also known as Wrapper, an alternative naming shared with the Adapter pattern) is a design pattern that allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class.1

Alexandre FILLATRE
  • 1,305
  • 11
  • 20
Andres
  • 10,561
  • 4
  • 45
  • 63
  • "you're trying to create an instance of a class, and then make that instance become an instance of other class. That's not possible in Java." Are you sure? What about the whole concept of polymorphism? If I have an instance of a String, I can also refer to that as an instance of an Object. – jordan May 10 '14 at 19:56
  • You can refer to a String instance through an Object variable, but it'll still be a String (which is a particular case of Object). – Andres May 10 '14 at 19:57
  • A String "is a" Object though. – jordan May 10 '14 at 19:58
  • The point is that once you create an instance of a class, you can't make it an instance of a different class than the one determined at creation time. – Andres May 10 '14 at 19:59
  • Andres is right. Decorator may be one of the answers. Another would be AOP for example (pretty close to decorator) – Alexandre FILLATRE May 10 '14 at 20:11
0

What you can do is the following :

  1. Have a Human and a SuperHero interface with their own methods to implement (done)
  2. have a HumanAndSuper abstract class, which implements the former 2 classes (that's the key here)
  3. In your HumanAndSuper class, add a private attribute that tells you if you person is currently a human or a superhero, and do the right logic about it
  4. In your Implementation class, implements your interface methods.

You now have an object (ex: peterParker) who can call all methods, from Human, SuperHero, and HumanAndSuper.

Furthermore, if you want to prevent (for instance) the use of attack() when in human form, you'd need to implement the interfaces methods in your HumanAndSuper class, and make the right checks (using the private attribute declared above).

There are other (safer) methods to achieve this behaviour, but they're more complicated.

Alexandre FILLATRE
  • 1,305
  • 11
  • 20