所以我有3个班级:
Item
GroupItem
扩展 Item
ProductItem
扩展项目我将一组Item
个对象传递给一个类,并希望根据类的类型执行不同的操作。
使用instanceof
是否可以接受这样做,或者我应该使用内部boolean isGroup()
方法,该方法将在初始化指定的子类时设置。
class Item {
protected boolean isGroup = false;
public boolean isGroupItem() { return isGroup; }
}
class GroupItem extends Item {
public GroupItem() {
isGroup = true;
}
}
class ProductItem extends Item {
public ProductItem() {
isGroup = false;
}
}
class Promotion {
// Item can be either a group or a list of items
private List<Item> items = new LinkedList<Item>;
public void addItem(Item itemObj) {
items.addItem(itemObj);
}
public List<Item> getItems() {
return items;
}
}
class Checker {
// Items retrieved from Promotion and passed from another class as array
public Checker(Item[] items) {
// either
if(items[0] instanceof GroupItem) {
// Do something ...
}
// or
if(items[0].isGroupItem()) {
// Do something ...
}
}
}
所以我的问题是:
提前致谢
答案 0 :(得分:3)
对要作为参数传递的实际类型使用不同的方法。
通常,使用instance of
表示模型中存在错误。
如果您需要针对不同的子类型使用不同的行为,则表示您实际上并未使用父类型。此外,您不得不知道实现细节,但情况并非如此。
如果您拥有的继承只是技术上的继承,请尝试使用组合而不是继承。
答案 1 :(得分:2)
这是您应该使用instanceOf
运算符的确切位置。
instanceof运算符将对象与指定类型进行比较。您 可以使用它来测试对象是否是类的实例,实例 子类的实现,或实现特定的类的实例 接口
没有必要跳过一个新方法或一些布尔属性来做这些事情。您可以通过check instanceOf轻松识别GroupItem
的特定对象。
您也可以使用GroupItem.class.isInstance(items[0])
来检查相同内容。喜欢 -
if(GroupItem.class.isInstance(items[0])) {
// Do something ...
}
答案 2 :(得分:1)
我想我会尝试定义为什么我需要知道它是否是一个群体。
假设是决定一个项目是否有资格参加促销活动,促销规则可能会改变:那么我会使用instanceof
,因为您不希望促销规则逻辑“污染”您的基本对象。
如果作为一个群组是您项目的重要属性,并且在各种情境中(不仅仅是促销规则)有用,我会将其包含在项目级别。
答案 3 :(得分:1)
instaceOf
运算符是更好的选择,但我也会考虑使用Visitor pattern。
interface Item{
void accept(CheckerVisitor checker);
}
class GroupItem implements Item{
void accept(CheckerVisitor checker){
checker.visit(this);
}
}
class OtherItem implements Item{
void accept(CheckerVisitor checker){
checker.visit(this);
}
}
class CheckerVisitor{
void visit(GroupItem groupItem){
//do specific things to GroupItem
}
void visit(OtherItem otherItem){}
}
class MyClassOfItems{
List<Item> items = ...;
for(Item item : items){
item.accept(new CheckerVisitor());
}
}
答案 4 :(得分:0)
因此,在阅读本文之后,我为我的解决方案选择了不同的路径。感谢所有帮助过的人。
我选择的解决方案让我甚至不会被对象的子类型所困扰(感谢Assylias和BalázsMáriaNémeth让我重新思考我的结构)因为我使用抽象类来获取我需要的信息。
abstract class Item {
public Item(...) {
initialise();
createSQLSegment();
}
protected String SQLSegment = "";
protected abstract void createSQLSegment();
public String getSQLSegment() {
return SQLSegment;
}
...
}
// Concrete class creates response
class GroupItem extends Item {
...
// Concrete method
protected void createSQLStatement() {
SQLStatement = "...SQL...";
}
}
class ProductItem extends Item {
...
// Concrete method
protected void createSQLSegment() {
SQLSegment = "...SQL..."
}
}
class Promotion {
// Item can be either a group or a list of items? extends Item>;
public void addItem(Item itemObj) {
items.addItem(itemObj);
}
public List<Item> getItems() {
return items;
}
}
class Checker {
// Items retrieved from Promotion and passed from another class as array
public Checker(Item[] items) {
...
for(Item item : Items) {
addPreparedSQLToBatch(item);
}
}
private void addPreparedItemToBatch(Item item) {
...
// No need to know concrete class
SQLString += Item.getSQLSegment();
...
}
}
再次感谢大家。
欢迎评论,我一直在学习: - )