2016-12-24 33 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` 
    } 

    // ... 
} 

我想有一個擴展ModelUser,但我不想在User重新實現create()。我只是想改變的table_name價值,並希望繼承create()使用子table_name

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

    // ... 
} 

我怎樣才能做到這一點?


我知道一個解決方案,我想補充setTableName()方法Model,但只能當table_name是非靜態的。然而,我需要它是靜態的,因爲我想create()是靜態的,這樣我就可以這樣做:User.create()

+0

這是行不通的。更好地將該值作爲參數傳遞給方法 – GurV

+0

@GurwinderSingh究竟是什麼阻止它成爲可能? –

+0

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

回答

1

,有一個呼籲Model類「創造」並不意味着有將自動爲靜態「創造」在延伸Model類用戶類方法靜態方法的事實 - 靜態方法屬於這個類,它們不是繼承的。如果你在子類上實現你自己的'create'方法,那麼它和Model類的'create'方法之間沒有關係。這聽起來像你想要一個Factory

如果你想堅持一種類似於迄今爲止所做的方法,類似這樣的事情可能會起作用。它將持久性邏輯放在一個地方,同時允許每個模型定義它自己的表名和數據映射。

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

家長無法訪問孩子的成員(並且正確如此)。看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中不可能?」 (反之亦然。)用不同的語言來說某種事情是可能的,完全是不可避免的,先驗無關緊要。 –

相關問題