2016-12-24 11 views
1

私はJavaでプロジェクトを進めており、MVCアーキテクチャを使用することに決めました。継承したメソッドを使って、サブクラスの 'スーパークラスの代わりに変数'を使用する

私はこのようになりますModelクラスを持っている:

public class Model { 
    static String table_name = null; 

    // ... 

    public static Model create(Map<String, Object> data) { 
     // insert `data` into database table `table_name` 
    } 

    // ... 
} 

私はModelを拡張するクラスUserを持つようにしたいが、私はUserで再実装create()したくありません。私はちょうどtable_nameの値を変更したいとサブクラスtable_name使用するように継承されたcreate()をしたい:

public class User extends Model { 
    static String table_name = "users"; 

    // ... 
} 

どのように私はこれを達成することができますか?


は私がModelsetTableName()メソッドを追加する解決策を知っているが、それはtable_nameは非静的である場合にのみ機能します。しかし、create()を静的にして、これを行うことができるようにするためには、静的にする必要があります。User.create()

+0

これは動作しません。パラメータとしてメソッドに値を渡す方が良い – GurV

+0

@ GurwinderSinghそれが可能にならないのはどういうことでしょうか? –

+0

Look [Here](http://stackoverflow.com/questions/2593258/is-it-possible-to-access-variable-of-subclass-using-object-of-superclass-in-poly) – GurV

答えて

1

Modelクラスに「作成」という静的メソッドがあるという事実は、自動的に静的があることを意味しないモデルクラスを拡張Userクラスのメソッド「を作成」 - 静的メソッドをクラスに属し、継承されません。サブクラスで独自の 'create'メソッドを実装すると、それとModelクラスの 'create'メソッドとの間には関係がありません。 Factoryがほしいと思うように聞こえます。

これまでのやり方と似たアプローチを採用したい場合は、このようなことが働く可能性があります。永続ロジックは1つの場所に保持され、各モデルで独自のテーブル名とデータマッピングを定義できます。

abstract class Model { 

    private PersistenceManager persistenceManager = new PersistenceManager(); 

    abstract String getTableName(); 
    abstract Model map(Object persistenceResult); 

    public void load(Map<String, Object> data) { 
     Object persistenceResult = persistenceManager.create(data, getTableName()); 

     //Set appropriate fields on this class. 
     map(persistenceResult); 
    } 
} 

class User extends Model { 

    @Override 
    String getTableName() { 
     return "Users"; 
    } 

    @Override 
    Model map(Object persistenceResult) { 
     //Mapping logic. 
     return null; 
    } 
} 

class PersistenceManager { 

    public Object create(Map<String, Object> data, String tableName) { 
     //Persistence logic. 

     //Return result of DB insert here. 
     return null; 
    } 
} 

class ModelFactory { 

    public static Model createModel(Class modelClass, Map<String, Object> data) { 
     Model model; 
     if (modelClass == User.class) { 
      model = new User(); 
     } else { 
      //Cater for other models. 
      throw new IllegalArgumentException("Invalid model."); 
     } 

     model.load(data); 

     return model; 
    } 
} 

次のように使用できます。

Map<String, Object> userData = new HashMap<>(); 
userData.put("name", "Bob"); 

Model user = ModelFactory.createModel(User.class, userData); 

(ジェネリックスのような)コードにはまだクリーンアップの余地がありますが、残しておきます。

+0

現時点では、私はGurwinder Singhが提供したものに固執すると思います。ソフトウェアアーキテクチャーとJavaの両方の面白い経験しかありません。私はLaravelとPHPの経験に基づいて簡単なものを構築しようとしています。正しい方向を指してくれてありがとう。 –

1

親は子供のメンバーにアクセスできません(正当な理由で)。 Look here

あなたができることは、タスクを実行する保護された方法(タブ名も受け入れます)を作成して代わりに使用することです。

public class Model { 
    static String table_name = "A"; 

    public static Model create(Map<String, Object> data) { 
     return create(data, table_name); 
    } 

    protected static Model create(Map<String, Object> data, String table_name) { 
     // logic here 
    } 
} 

public class User extends Model { 
    static String table_name = "B"; 

    public static Model create(Map<String, Object> data) { 
     return create(data, table_name); 
    } 
} 
+0

私は何ですかしようとすることはPythonでも可能です。 [セクション9.6プライベート変数](https://docs.python.org/3/tutorial/classes.html#private-variables)の例を参照してください。 Javaで実行できないと確信していますか? –

+0

Pythonで本当に可能かどうかはわかりません(そうでなければ、継承パラダイム全体が崩れてはいけません)。しかし、Javaにはないと確信しています。 – GurV

+0

「WATFORでは私がやろうとしていることは可能ですが、なぜSNOBOLではそれができないのですか?」 (あるいはその逆)何かが異なる言語で可能であることは、まったく不可避的に、先験的に無関係です。 –

関連する問題