Estoy enfrentando un problema en Java.

Necesito tener varias clases con los mismos atributos (por ejemplo, una posición y un booleano isWalkable).

Pero no quiero que estas clases hereden de un elemento de clase porque eso me impediría usar la herencia más adelante.

Pensé en una interfaz (para que la interfaz tenga los atributos), pero aparentemente no puedes tener una interfaz heredada de una clase.

Debe haber una manera porque de lo contrario tendría que copiar / pegar mis atributos y sus métodos.

Gracias de antemano por cualquiera que tenga una idea sobre cómo superar este problema.

-1
Irindul 25 dic. 2016 a las 18:28

3 respuestas

La mejor respuesta

Sospecho que puede necesitar una interfaz de todos modos , si desea tratar sus objetos genéricamente, p. pase sobre todos ellos y dibuje cada uno. P.ej. asumiendo que sus elementos incluyen "gatos" y "casas":

interface Element{
   public point getPosition();
   public boolean isWalkable();
}
class Cat implements Element{
   private Point position;
   private String catBreed; // example of cat-specific data
   public point getPosition() {return position;}
   public boolean isWalkable() {return true;} // cats can walk
   ...
}
class House implements Element{
   private Point position;
   private String streetAddress; // example of house-specific data
   public point getPosition() {return position;}
   public boolean isWalkable() {return false;} // houses cannot walk  
   ..
}

// Finally, using that common interface:
Element[] allGameObjects= {new Cat(...), new Cat(...), new House(...) };
for(Element e:allGameObjects) 
   draw(e, e.getPosition());

Eso fue lo suficientemente bueno para varios sistemas que escribí ... pero como otras respuestas mencionaron correctamente, podría refactorizar el uso de la composición, sin embargo, podría no ser un 100% claro. Quiero decir, puedo entender si sientes que Cat o House deben ser manejados independientemente de su posición ... pero ¿qué pasa con isWalkable?

// Position is easy to separate:
class Cat { String catBreed; ... }
class House{ String streetAddress; ... }

class ElementWrapper implements Element{
   Point position;
   Object  theObject; // could hold Cat or House
   public Point getPosition() {return position;}
   // however, isWalkable is a bit tricky... see remark below
}

Pero 'isWalkable' es complicado porque en el polimorfismo clásico esperarías que House / Cat te diga si pueden caminar (lo que significa que deberían implementar una interfaz de todos modos). Si no quiere (o no puede) tenerlo, puede comprometer el polimorfismo y hacer algo en la línea de instancia de (si el Objeto es una instancia de Cat, entonces puede caminar, si es una instancia de House, no puede caminar, etc.).

0
Pelit Mamani 25 dic. 2016 a las 16:57

Puede extender una clase base abstracta (que no contiene nada) o puede usar el patrón Decorador como alguien sugirió en los comentarios, para obtener más información relacionada con el patrón Decorador puede leer esto enlace.

0
Kiran Kumar 25 dic. 2016 a las 15:59

Para esto, consideraría composición sobre herencia.

public class Main {

    public static void main(String[] args) {
        AgentWrapper agentWrapper = new AgentWrapper(new Agent1(), false, 1);
        System.out.println("isWalkable: " + agentWrapper.isWalkable());
        System.out.println("position: " + agentWrapper.getPosition());
        agentWrapper.getAgent().doSomething();
    }
}

interface Agent {
    void doSomething();
}

class Agent1 implements Agent {

    public void doSomething() {
        System.out.println("Agent1");
    }
}

class Agent2 implements Agent {

    public void doSomething() {
        System.out.println("Agent1");
    }
}

class AgentWrapper {

    private final Agent agent;  //Wrapped instance.
    private final boolean isWalkable;
    private final int position;

    public AgentWrapper(Agent agent, boolean isWalkable, int position) {
        this.agent = agent;
        this.isWalkable = isWalkable;
        this.position = position;
    }

    public Agent getAgent() {
        return agent;
    }

    public boolean isWalkable() {
        return isWalkable;
    }
1
Riaan Nel 25 dic. 2016 a las 16:24