[英]Which class the interface type instance is from
I have an interface: 我有一个界面:
public interface Myinterface{
...
}
The interface is implemented by three classes, let's name them ClassOne
, ClassTwo
, ClassThree
. 该接口由三个类实现,我们将其命名为ClassOne
, ClassTwo
, ClassThree
。
Now, I have a helper method which returns an instance of type MyInterface
. 现在,我有一个帮助程序方法,该方法返回MyInterface
类型的实例。 eg 例如
MyInterface myInstance = MyHelper.getOneInstance();
I what to check whether the returned instance myInstance
is a instance of ClassThree
or not, how to do it in Java? 我该如何检查返回的实例myInstance
是否是ClassThree
的实例,如何在Java中进行呢?
(I know there is instanceof
keyword in Java, but it is checking the other way around. I want to know which concrete class the instance is from.) (我知道Java中有instanceof
关键字,但是它正在反过来检查。我想知道实例来自哪个具体类。)
To check whether an object is an instance of a specific class, you can use the getClass()
method from the Object
class. 要检查对象是否是特定类的实例,可以使用Object
类中的getClass()
方法。
For example this is true only if myInstance
is a ClassThree
object: 例如,仅当myInstance
是ClassThree
对象时,才为true:
if (myInstance.getClass() == ClassThree.class)
Now, generally this is not necessarily more robust as it defeats some of the benefits of OOP. 现在,通常这并不一定会更强大,因为它会破坏OOP的某些优势。
A more OOP way to proceed is introducing a method that you could use to do this check. 另一种OOP方式是引入一种可用于执行此检查的方法。
As you don't give a specific example, it is hard to give an adapted example but assume that you want to save some classes if these are recordable. 由于您没有给出具体的示例,因此很难给出一个经过修改的示例,但是假设您想保存一些可记录的类。
You could introduce a boolean isRecordable()
method in your interface. 您可以在界面中引入boolean isRecordable()
方法。
In this way you could do : 通过这种方式,您可以:
if (myInstance.isRecordable()){
...
}
Pretty sure instanceof ClassThree
is true if getOneInstance()
returns a ClassThree object. 如果getOneInstance()
返回ClassThree对象,则可以getOneInstance()
肯定instanceof ClassThree
为true。
while (true){
MyInterface impl = MyHelper.getOneInstance()();
if(impl instanceof Class1){
System.out.println("was 1");
} else if(impl instanceof Class2){
System.out.println("was 2");
} else if(impl instanceof Class3){
System.out.println("was 3");
}
}
The difference between instanceof
and getClass()
implementations is that instanceof will look up the hierarchy so instanceof
和getClass()
实现之间的区别在于instanceof
将查找层次结构,因此
new ClassThree() instanceof MyInterface
is true whereas, new ClassThree() instanceof MyInterface
为true,而
new ClassThree().getClass() == MyInterface.class
is false. new ClassThree().getClass() == MyInterface.class
为false。
Try the visitor pattern 尝试访客模式
Often you don't want to know the implementing class name, but want to have the correct behaviour ensured. 通常,您不想知道实现类的名称,但是想要确保正确的行为。 The visitor pattern is a layer of indirection, with its own pitfalls, but generally speaking often the way to go. 访客模式是一个间接层,具有其自身的陷阱,但通常来说通常是要走的路。
I think it is better than instance of
because sometimes your object is an instance of different classes/interfaces and therefore your check must be considering all possible combinations and not return early. 我认为它比instance of
更好instance of
因为有时您的对象是不同类/接口的实例,因此您的检查必须考虑所有可能的组合,并且不能尽早返回。 Another downside is, that if you use getClass()
your code will become cluttered with if
s accross your project, whereas the Visitor gives you a central place. 另一个缺点是,如果你使用getClass()
你的代码会变得凌乱if
小号进行的跨项目,而游客给你一个中心位置。
public interface MyVisitor<T> {
T visitClassOne(ClassOne classOne);
T visitClassTwo(ClassTwo classTwo);
T visitClassThree(ClassThree classThree);
}
public interface MyInterface {
Class acceptVisitor(MyVisitor myVisitor);
}
public class ClassOne implements MyInterface {
@Override
Class acceptVisitor(MyVisitor myVisitor) {
return myVisitor.visitClassOne(this);
}
}
//or maybe call the desired methods directly, instead of returning the
//Class an call the desired methods based on the result.
public class ClassVisitor implements MyVisitor<Class> {
@Override
Class visitClassOne(ClassOne classOne) {
return classOne.getClass();
}
@Override
Class visitClassTwo(ClassTwo classTwo) {
return classTwo.getClass();
}
@Override
Class visitClassThree(ClassThree classThree) {
return classThree.getClass();
}
}
so sowhere else you could do: 所以在其他地方你可以做:
MyInterface myClass = new ClassOne();
Class myClassClass = myClass.acceptVisitor(new ClassVisitor());
this is untestet, I just wrote it down. 这是untestet,我只是写下来。 I have to admit for returning Class
this is not the tiptop very best idea, but as already said, often you don´t want to do that. 我不得不承认,返回Class
并不是最好的想法,但是正如已经说过的,通常您不想这样做。
Have you tried the "is" keyword? 您是否尝试过“ is”关键字? if (myInstance is ClassThree) { . 如果(myInstance是ClassThree){。 . 。 . 。 } }
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.