2010-12-01 2 views
1

У меня есть суперкласс Shape и классы Triangle, Square и т. Д. Расширяют форму. У меня есть два текущих вопроса:Делегирование методов для подклассов в Java

  1. Мой метод Triangle extends Shape не скомпилирован. Он должен вернуть форму, а не треугольник.
  2. Я хочу скрыть этот метод. Его следует вызывать только из суперкласса Shape.
public class Shape { 
    public static Shape createShapeFromXML(String xml) { 
    String type = parse(xml); 
     if (type.equals("Triangle") { 
     Triangle.createShapeFromXML(xml); 
     } else if (...) { 
     // ... 
    } 
    } 
} 

public class Triangle extends Shape { 
    public static Triangle createShapeFromXML(String xml) { 
    .... 
    } 
} 

public static void main(String[] args) { 
    String xml = ... 
    Shape s = Shape.createShapeFromXML(xml); 
} 

Как решить эти проблемы?

ответ

6

Почему бы вам не сохранить один статический метод в суперклассе и вернуть его подкласс Shape? Подпись останется прежней, потому что треугольники имеют отношение к Shape.

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

Другого подход будет использовать Factory шаблон. У вас может быть ShapeFactory ... Это хорошая идея, потому что создание синтаксического анализа xml не является проблемой классов Shape. Отделите свои проблемы. Ссылка на wikipedia хорошо описывает шаблон, но вам может понадобиться более простой пример. См. this.

+1

В частности, я считаю, что это относится к примеру абстрактной фабрики. Я действительно не знаю, почему GoF классифицировал их как два отдельных шаблона. – 2010-12-01 03:24:33

+0

+1 к заводской шаблон. Это не означает создание объекта класса fapr – 2010-12-01 03:28:26

1

Для компиляции кода вам необходимо объявить public static Shape createShapeFromXML(String xml) в классе Triangle.

 

public class Shape { 

    public static void main(String[] args) { 
      String xml = "Triangle"; 
      Shape s = Shape.createShapeFromXML(xml); 
      System.out.println(s.toString()); 
    } 

    public static Shape createShapeFromXML(String xml) { 
     Shape aShape = null; 

     if (xml.equals("Triangle")) { 
     aShape = Triangle.createShapeFromXML(xml); 
     } 
     return aShape; 
    } 
} 

class Triangle extends Shape { 

    public static Shape createShapeFromXML(String xml) { 
     return new Triangle(); 
    } 

    @Override 
    public String toString() { 
     return "Triangle"; 
    } 
} 

 

System.out.println (s.toString()); в основном методе выходы «Треугольник», это доказывает, что создается форма треугольника.

2

// 2. I want to hide this method. It should only be callable from superclass Shape

Вы можете сделать метод Shape final для того, чтобы заблокировать реализацию. Даже ваш перегруженный метод, который возвращает тип подкласса (Triangle в вашем примере), будет отмечен компилятором.

public static final Shape createShapeFromXML(String xml) { ... } 

EDIT:

в ответ на разговор в комментариях, для доказательства я приведу следующее:

public class Shape { 
    public static final Shape createShapeFromXML(String xml) { 
     if (xml.equals("Triangle")) {//removed parse for demo compliation 
     return Triangle.createShapeFromXML(xml); 
     } else { 
     return new Shape(); 
     } 
    } 
} 

public class Triangle extends Shape{ 
    public static Triangle createShapeFromXML(String xml) { 
     return new Triangle(); 
    } 
} 

пытается скомпилировать выше приведет к ошибке компилятора:

mybox:src akf$ javac Triangle.java 
Triangle.java:3: createShapeFromXML(java.lang.String) in Triangle cannot override createShapeFromXML(java.lang.String) in Shape; overridden method is static final 
    public static Triangle createShapeFromXML(String xml) { 
           ^
1 error 

Это можно объяснить с помощью JLS путем ссылки две секции:

от 8.4.6.2 Скрытие (методами класса):

If a class declares a static method, then the declaration of that method is said to hide any and all methods with the same signature in the superclasses and superinterfaces of the class that would otherwise be accessible to code in the class.

, а затем из 8.4.3.3 final Методы:

A method can be declared final to prevent subclasses from overriding or hiding it. It is a compile-time error to attempt to override or hide a final method.

Ввод два вместе, добавление final к сигнатуре статического метода защитит этот метод от скрытия подклассами.Он обеспечит проверку времени компиляции.

Смежные вопросы