简体   繁体   English

java-从抽象类创建对象的实例

[英]java - create instances of objects from abstract class

I have an abstract Record class that represents database records which has two abstract methods: getTable() and getColumns(). 我有一个抽象的Record类,它表示具有两个抽象方法的数据库记录:getTable()和getColumns()。 I then have a Customer class that extends Record and i implement those abstract methods in this class. 然后,我有一个Customer类扩展了Record,并在此类中实现了这些抽象方法。

I'm trying to figure out how i can get a list of all Customers but keep the method as reusable as possible so i'd prefer a getAllRecords(Record record) method than getAllCustomers() method. 我试图弄清楚如何获取所有客户列表,但要使该方法尽可能地可重用,所以我比getAllCustomers()方法更喜欢使用getAllRecords(Record record)方法。

Here's what i have thus far. 到目前为止,这就是我所拥有的。 I can't create a new Record() object because it's abstract and need to create an instance of the class that was passed in. 我无法创建新的Record()对象,因为它是抽象的,需要创建传入的类的实例。

//i'd like to do something like this to get all of the Customers in the db 
// datasource.getAllRecords(new Customer());

public List<Record> getAllRecords(Record record) {
    List<Record> records = new ArrayList<Record>();

    Cursor cursor = database.query(record.getTable(),
        record.getColumns(), null, null, null, null, null);

    cursor.moveToFirst();
    while (!cursor.isAfterLast()) {
      Record record = cursorToRecord(cursor, record);
      records.add(record);
      cursor.moveToNext();
    }
    // Make sure to close the cursor
    cursor.close();
    return records;
  }

  private Record cursorToRecord(Cursor cursor, Record record) {


    Record record = new Record(); <-- somehow clone a new instance of the record that was passed in

    record.setId(cursor.getLong(0));
    record.setValue("aKey",cursor.getString(1));
    return record;
  }

would having some kind of RecordRegistry object make sense instead of having individual factory classes for each subclass of Record? 将有某种RecordRegistry对象有意义,而不是为Record的每个子类提供单独的工厂类?

class RecordRegistry{

    private static final List<Record> RECORDS;

    static {
            final List<Record> records = new ArrayList<Record>();
            records.add(new Customer());
            records.add(new Company());

            RECORDS = Collections.unmodifiableList(records);
    }

    public List<Record> allRecords(){

        return RECORDS;
    }

    public Record buildRecord(Class cClass){

        String className = cClass.getName().toString();

        if(className.equalsIgnoreCase("customer")){
            return new Customer();
        }else if(className.equalsIgnoreCase("company")){
            return new Company();
        }
        return null;
    }
}

You can get the class of the Record , provided that all the subclasses of Record will have a no-arg constructor. 你可以得到类的Record ,前提是所有子类Record将有一个无参数的构造函数。

Record newRecord = record.getClass().newInstance();

Note that you can just pass the class instead of the object itself. 请注意,您可以只传递类而不是对象本身。

You can also pass a factory that will be responsible to instanciate the right class. 您还可以通过一家工厂来负责维护合适的班级。

interface RecordFactory {
    Record create();
}

class CustomerFactory implements RecordFactory {
    Record create() {
        return new Customer();
    }
}

public List<Record> getAllRecords(RecordFactory factory) {
    ...
    for(...) {
        ...
        Record record = factory.create();
        ...
    }
    ...
}

An odd use case. 一个奇怪的用例。 I would make the cursorToRecord method abstract. 我将把cursorToRecord方法抽象化。 That pushes the logic into each class, which knows how to build itself from a Cursor . 这将逻辑推到每个类中,每个类都知道如何从Cursor构建自身。

public abstract Record cursorToRecord(Cursor cursor, Record record);

Not directly answering your Q, but take a look at the Android guides on Content Providers ( https://developer.android.com/guide/topics/providers/content-providers.html ). 不直接回答您的问题,而是查看内容提供者上的Android指南( https://developer.android.com/guide/topics/providers/content-providers.html )。 They allow for flexible data access amongst other benefits. 它们允许灵活的数据访问以及其他好处。 I found them worth the initial learning and setup effort (especially when used w/ Loaders) 我发现它们值得进行初步的学习和设置(特别是在与装载机一起使用时)

那反射呢?

Record newRecord = record.getClass().newInstance();

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM