2016-05-20 3 views
-1

У меня есть интерфейс. Один из моих методов принимает в качестве аргумента объект этого интерфейса. В зависимости от конкретного класса, я хочу построить другой объект.Как интерпретировать и использовать класс, заданный объектом интерфейса?

public interface Shape { 
    public void draw(); 
} 

public class Circle implements Shape { 
    private int radius; 
    //constructor etc. 

    public void draw() { 
    System.out.println("CIRCLE!"); 
    } 

    public int getRadius() { 
    return radius; 
    } 
} 

public class Square implements Shape { 
    private int side; 

    //constructor etc. 

    public void draw() { 
    System.out.println("SQUARE!"); 
    } 

    public int getSide() { 
    return side; 
    } 
} 


public class MyClass { 
    public void myJob(Shape shape) { 
    if (shape.getClass().toString().equals("Circle")) { 
     // some missing code...what to do here? type cast? transform? 
     int radius = shape.getRadius(); 
    } 
    } 
} 

Как принимать интерфейс Shape, а затем получить radius или side из них, в зависимости от типа класса?

+0

Какой вопрос? – tfosra

+1

Вы должны изучить полиморфизм, чтобы решить вашу проблему, вместо того, чтобы пытаться применить к кругу или квадрату. –

+0

Итак, вы хотите иметь дело с интерфейсом, а не с конкретным классом, чтобы абстрагировать любые детали реализации, а затем, когда вы фактически овладеете таким интерфейсом, вы настаиваете на том, чтобы точно знать, с каким объектом вы имеете дело, чтобы вы могли вызовите некоторый метод, который интерфейс не предлагает. Это совершенно бессмысленно. Вам будет лучше с несколькими методами myJob, каждый из которых будет иметь другой тип (круг, квадрат и т. Д.). –

ответ

2

Во-первых, нет необходимости использовать отражения для этого, вы можете использовать ключевое слово instanceof

public void myJob(Shape shape) { 
    if (shape instanceof Circle) { 
     // some missing code...what to do here? type cast? transform? 
     int radius = shape.getRadius(); 
    } 
} 

Тогда, что вы хотите сделать, это бросить вашу форму в круг, так что вы может относиться к нему, как круг:

public void myJob(Shape shape) { 
    if (shape instanceof Circle) { 
     Circle circle = (Circle) shape; 
     // Some Circle job 
     int radius = circle.getRadius(); 
    } 
} 

Наконец, если, как вы сказали, что вы хотите применить различные методы лечения для различных реализаций Shape, вы можете явно ввести параметр:

public void myJob(Circle circle) { 
    // Some Circle job 
} 

public void myJob(Square square) { 
    // Some Square job 
} 

Тем не менее, лучший способ сделать это будет использовать интерфейс Shape:

public interface Shape { 
    void draw(); 
    void myJob(); 
} 

public class MyClass { 
    public void myJob(Shape shape) { 
     shape.myJob(); 
    } 
} 

}

+2

Наличие экземпляра оператора для исправления сломанной абстракции не является хорошим ответом. – John

+0

В итоге я включил myJob() в моей форме. поскольку 'shape' всегда будет ссылаться на правильный метод. – ritratt

2

Весь код, который является Shape, должен располагаться в методах, переопределяемых каждым подклассом.

public interface Shape { 
    public void draw(); 
    public int getMeasure(); 
} 

public class Circle implements Shape { ... } // The code for the methods in Shape should be written here. 

public class Square implements Shape { ... } 

public class MyClass { 
    public void doWork(Shape shape) { 
     int measure = shape.getMeasure(); 
    } 
} 

Как правило, глядя вверх класс по имени во время выполнения ненужной нервотрепки, которую можно избежать.

Отредактировано для вопроса.

0

Вы можете проверить, является ли это экземпляром Circle, используя instanceof, а затем передайте его в круг, если это так.

if (shape instanceof Circle) { 
    Circle circle = (Circle)shape; 
    int radius = circle.getRadius(); 
} 
Смежные вопросы