2016-12-24 69 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中不可能?” (反之亦然。)用不同的语言来说某种事情是可能的,完全是不可避免的,先验无关紧要。 –