3

私はいくつかのシステムを持つアプリケーションを開発しています (私の場合、システムは特定のタスクを処理するアプリケーションのロード可能なコンポーネントです。たとえば、翻訳、設定処理、オーディオなど...)。これらのシステムはいくつかの一般的な方法を共有しているため、インターフェースを作成しました。

public interface System {
    public void initialize();
    public void uninitialize();
}

ただし、各システムには、システムが実装するタスクに対応する独自のメソッドがあります。これが私のシステムの2つの例です

最初のものは設定を保存します:

public class SettingsSystem implements System {
    @Override
    public void initialize() {
        // few lines of code here
    }

    @Override
    public void uninitialize() {
        // few lines of code here
    }

    public Object getSetting(String key) {
        // returns a setting
    }
}

そして、翻訳を行う言語システム。

public class LanguageSystem implements System {

    @Override
    public void initialize() {
        // few lines of code here
    }

    @Override
    public void uninitialize() {
        // few lines of code here
    }

    public void setLanguage(String language) {
        // sets language
    }

    public boolean load( String name) {
        // loads a file
    }

    public String translate(String key) {
        // returns translation of a key
    }
}

System インスタンスを静的な HashMap に格納します。これは、アプリ内のあらゆる場所で System インスタンスにアクセスしたいためです。キーで任意のシステムを返す静的メソッドを作成しました。

public class App {
    // note: System is the System interface I created
    private static Map<String, System> systems = new HashMap<String, System>();

    public static Object getSystem(String key) {
        return systems.get(key);
    }
}

App.getSystem() メソッドを呼び出すと、オブジェクトが返されます。だから電話したら…

App.getSystem("settings");

...正しいアイテムをオブジェクトとして返します。しかし問題は、SettingsSystem の getSetting() メソッドを呼び出すことができないことです。

このように実装すると:

public static System getSystem(String key) {
    return systems.get(key);
}

initialize() または uninitialize() メソッドを呼び出すことはできますが、まだ getSettings() メソッドを使用できません。

私が欲しいのは、 App.getSystem() メソッドを呼び出すときに、その中にある正しいタイプのオブジェクトを返すことです。例:

App.getSystem("settings"); // I want it to return a SettingsSystem object
// So I can do:
String width = App.getSystem("settings").getSetting("width");

App.getSystem("language"); // I want it to return a LanguageSystem object
// So I can do:
String welcome = App.getSystem("language").translate("hello_world");

これはどのように可能ですか?前もって感謝します。

アップデート

あなたの助けに基づいて、各システムの getter メソッドを宣言することにしました。

public SettingsSystem getSettingsSystem() {
    return (SettingsSystem) system.get("settings");
}

アドバイスありがとうございます!

4

4 に答える 4

3

次のように正しい型にキャストする必要があります。

SettingsSystem settingSystem = null;
System system = App.getSystem("settings");
if (system instanceof SettingsSystem) {
    settingSystem = (SettingSystem) system;
}
settingSystem.getSetting("width");

もちろん、これは関連するnullチェックなどで行います。

ただし、キャストを回避できる場合は好みです。代わりに、実装クラスで 2 つの別個のマップを保持できますか?

または、 の実装がいくつかあるように見えるので、キャストを分離SystemするPatricia Shanahan のソリューション #2 を使用します。

于 2013-05-07T08:59:07.813 に答える
2

呼び出しからの戻り値の型を含む式の型は、コンパイル時に固定されます。同じオブジェクト内の同じメソッドに、いくつかの異なる戻り値の型を持たせることはできません。

次の 2 つのオプションがあります。

  1. 型 Object を返し、呼び出し元でキャストします。
  2. タイプごとに異なる getXXXSystem メソッドを宣言します。getLanguageSystem の戻り値の型は LanguageSystem です。
于 2013-05-07T09:00:57.697 に答える
1

getSystem() メソッドは System インスタンスを返すため、System インターフェイスで定義されているメソッドにのみアクセスできます。

具体的な実装クラスで定義されているメソッドにアクセスする場合は、最初にオブジェクトをそのクラスにキャストする必要があります

于 2013-05-07T09:02:59.823 に答える