简体   繁体   English

接口类型实例来自哪个类

[英]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 . 该接口由三个类实现,我们将其命名为ClassOneClassTwoClassThree

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: 例如,仅当myInstanceClassThree对象时,才为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 instanceofgetClass()实现之间的区别在于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.

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