簡體   English   中英

將方法委托給Java中的子類

[英]Delegating methods to subclasses in Java

我有一個超類Shape,而Triangle,Square等類則擴展Shape。 我有兩個當前問題:

  1. 我的方法Triangle extends Shape無法編譯。 它必須返回一個Shape而不是Triangle。
  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);
}

我該如何解決這些問題?

您為什么不在超類中保留一個靜態方法,並讓它返回適當的Shape子類? 簽名將保持不變,因為Triangles與Shape具有is-a關系。

您可以將超類上的方法設為私有,以獲取所需的訪問限制...

另一種方法是使用Factory模式。 您可能有一個ShapeFactory ...這是一個好主意,因為創建xml解析與Shape類無關。 分開關注。 Wikipedia鏈接擅長描述模式,但您可能需要一個更簡單的示例。 看到這個

// 2.我要隱藏此方法。 它只能從超類Shape調用

您可以使Shape方法成為final方法,以鎖定實現。 即使您的返回子類類型的重載方法(在示例中為Triangle )也會被編譯器標記。

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

編輯:

為了回應評論中的對話,為提供證據,我提供以下內容:

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隱藏(通過類方法)

如果一個類聲明了一個靜態方法,則稱該方法的聲明隱藏了該類的超類和超接口中具有相同簽名的所有方法,否則該類中的代碼將可以訪問這些方法。

然后從8.4.3.3 final方法開始

可以將方法聲明為final,以防止子類覆蓋或隱藏它。 嘗試覆蓋或隱藏最終方法是編譯時錯誤。

將兩者放在一起,將final添加到靜態方法的簽名中,可以保護該方法不被子類隱藏。 它將強制執行編譯時檢查。

為了使代碼編譯,您需要在Triangle類中聲明public static Shape createShapeFromXML(String xml)


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()); 在main方法的輸出“ Triangle”中,這證明正在創建Triangle形狀。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM