我看到一个类“AttributeSelectedClassifier”曾经通过以下方式创建:
AttributeSelectedClassifier classifier = new AttributeSelectedClassifier();
classifier.setClassifier(base);
classifier.setEvaluator(eval);
以上这个对我来说很自然。但是下一个呢。
classifier = new AttributeSelectedClassifier();
((AttributeSelectedClassifier)classifier).setClassifier(base);
((AttributeSelectedClassifier)classifier).setEvaluator(eval);
我认为它应该是对的,但我不太确定将分类器定义为((AttributeSelectedClassifier)分类器)的方法,如何理解这种用法?
答案 0 :(得分:2)
这意味着分类器变量被声明为AttributeSelectedClassifier
的超类或超接口,并且您需要调用未在类或接口中定义但仅在AttributeSelectedClassifier
上定义的方法。此表示法将变量转换为AttributeSelectedClassifier
:
Object classifier = new AttributeSelectedClassifier();
// classifier is a AttributeSelectedClassifier, but references as Object
// to call the following method, we need to cast it to AttributeSelectedClassifier
((AttributeSelectedClassifier)classifier).setClassifier(base);
((AttributeSelectedClassifier)classifier).setEvaluator(eval);
这通常是设计问题的标志。方法应该在超类或接口中,或者变量应该声明为AttributeSelectedClassifier
。
答案 1 :(得分:1)
此:
((AttributeSelectedClassifier)classifier)
不是“定义”或“声明”分类器 - 它是投射它。据推测,在这种情况下,classifier
被声明为AttributeSelectedClassifier
的某个超类。但代码并不是特别清楚。我将第二位代码重写(假设您不能将classifier
的声明更改为):
AttributeSelectedClassifier temp = new AttributeSelectedClassifier();
temp.setClassifier(base);
temp.setEvaluator(eval);
classifier = temp;
这样,您可以在为较不强类型的AttributeSelectedClassifier
变量指定值之前使用classifier
的所有方法。
(我可能会使用比temp
更清晰的名称,但是我们没有足够的上下文来确定这样的名称是什么。)
答案 2 :(得分:1)
通过执行((AttributeSelectedClassifier)classifier)
投射(“强制”)classifier
对象的行为就像AttributeSelectedClassifier
的实例。
classifier
变量之前可能已声明为AttributeSelectedClassifier的超类。
答案 3 :(得分:1)
请看下面的代码。 Person实现CanWalk
接口。如果您按照main方法中所示分配Person
到CanWalk
接口,这是一种常见做法,您只能调用CanWalk
接口中指定的方法,即{{1 }}。如果您要调用walk()
,在f()
界面中声明 ,那么您将使用您在帖子中指定的第二种机制。即强制它到CanWalk
类,然后调用该方法。
对于API的用户(此处的主要方法)来说,在使用对象时使用正确的抽象是一种很好的做法。对于例如如果客户主要关注移动Person,那么它应该使用CanWalk。这样,客户端不会受到与移动无关的Person类更改的影响。请阅读this article了解详情。
Person