多个子类,如何实例中的任何一个?

时间:2013-10-14 21:37:41

标签: java class dynamic subclass

这有点难以解释,但我会尽我所能。

我希望有多个项目,当点击时,每个项目都有不同的结果。其余的,它们都有相同的变量。所以基本上,我有一个类Item,子类Ball,Rope,Book,还有很多,还有更多。如果我愿意,我希望能够轻松添加项目。 Item类有一个String名称,String描述和每个子类覆盖的方法'onUse'。

我想尽可能动态处理这个问题,这意味着我想在我的Frame / Activity中使用一个方法(这适用于Android,但Java适用)来执行该方法。

我将其用于单一方法:

public void useItem(Item i)
{
    i.onUse();
}

我的问题是我在数据库中保存了不同的项目。我想随机抓取数据库中的一个项目并实例化它;除了我无法知道将其实例化为哪个子类。我尝试在数据库中保存数据类型,但这并没有真正解决... Pseudocode:

//Database cursor stuff
//...
                String itemType = c.getString(6);

                //Get the class name if possible
                Class itemClass= null;
                try {
                    itemClass = Class.forName(itemType);
                } catch (ClassNotFoundException)
                    e.printStackTrace();
                }

            Item l = null;
            // Check here what type it is!
            if (itemClass.equals(Ball.class)) {
                l = new Ball(name,description);

            } else if(lootClass.equals(Book.class)){

                l = new Book(name,description); 
            }

看到有这么多不同的项目,这不是很好,因为我必须遍历大量的类(加上我经常得到ClassNotFoundException)

你说什么,StackOverflow?什么是最好的方法?

2 个答案:

答案 0 :(得分:2)

在你的情况下,我会使用工厂方法模式(又名工厂模式)。

工厂方法模式是一种创造模式。创作模式抽象出来 对象实例化过程通过隐藏如何创建对象并使系统独立于对象创建过程。

让我们尝试实现它应该如何工作:

<强>模型

public abstract class Model {  
   protected abstract void init();
}

图书

public class Book extends Model {
 @Override
protected void init() {
    System.out.println("I'm a Book");
}
}

<强>球

public class Ball extends Model {
    @Override
protected void init() {
    System.out.println("I'm a Ball");
}
}

<强> DbModelFactory

public abstract class DbModelFactory {
    public abstract Model getModel(int modelId);
}

<强> SimpleDbModelFactory

public class SimpleDbModelFactory extends DbModelFactory  {

    @Override
    public Model getModel(int modelId) {
        Model model = null;
        if(modelId == Const.MODEL_BOOK) {

            model = new Book();
        }
        else if(modelId == Const.MODEL_BALL) {

            model = new Ball();
        }
        else {// throw Exception

        }
        return model;
    }
}

<强> CONST

public class Const {
    public static final int MODEL_BOOK = 0;
    public static final int MODEL_BALL = 1;
}

<强>启动

public class Launcher {
  public static void main(String[] args) {
    DbModelFactory factory  = new SimpleDbModelFactory();
    Model book = factory.getModel(0);
    book.init(); // I'm a Book

    Model ball = factory.getModel(1);
    ball.init(); //I'm a Ball
    }
}

工厂模式返回多个产品子类中的一个。你应该使用工厂 pattern如果你有一个超类和一些子类,并且基于提供的一些数据,你必须返回其中一个子类的对象

现在我们有2 Models bookball,我们并不关心两者实际上都是Model

答案 1 :(得分:1)

工厂模式可能是要走的路。如果将完全限定名称存储在数据库中,则可以创建一个读取值的工厂并使用以下内容实例化新项目:

Item item = (Item) Class.forName(theDBField).newInstance();
item.setName(name);
item.setDescription(desc);

这意味着一个更简洁的工厂,不必了解它可以构建的所有类。我真的不喜欢每次添加新实现时都要更新工厂,这是一种避免它的简单方法。

要执行此操作,您必须将getter和setter添加到项目界面。