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

    // ... 
} 

Я хочу иметь класс User, расширяющий Model, но я не хочу, чтобы повторно реализовать create() в User. Я просто хочу, чтобы изменить значение 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

Тот факт, что существует статический метод, который называется «создать» на классе модели не означает, что автоматически будет статическим «создать» метод на класс User, который расширяет класс модели - статические методы принадлежат классу, и они не унаследованы. Если вы реализуете свой собственный метод «create» в подклассе, нет никакой связи между этим и методом «create» в классе Model. Похоже, вы хотите 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); 

В коде есть место для очистки (например, с помощью Generics), но я оставлю это до вас.

+0

На данный момент, я думаю, я буду придерживаться того, что предоставил Гурвиндер Сингх. У меня есть только поверхностный опыт работы как с архитектурой программного обеспечения, так и с 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?» (Или наоборот). Что-то возможно на другом языке совершенно, неизбежно, априорно неактуально. –

Смежные вопросы