Java 如何在多态函数中传递父类实例而不是子类实例?

Java 如何在多态函数中传递父类实例而不是子类实例?,java,generics,Java,Generics,我有两个类Event1和Event2。在运行时,我想使用java反射创建Event1或Event2的实例,并将其作为参数传递给另一个函数。该函数是一个多态函数,它根据输入参数类型调用相应的功能 因为我不知道在运行时可能需要创建哪种类型的子事件实例,所以我从“event”类扩展了两个子类,并创建了一个父类实例。我的问题是,我是否可以将“Event”类的实例作为参数传递,该参数将在运行时解析为多态函数的一个子类 public void update(Event1); public void upda

我有两个类
Event1
Event2
。在运行时,我想使用java反射创建
Event1
Event2
的实例,并将其作为参数传递给另一个函数。该函数是一个多态函数,它根据输入参数类型调用相应的功能

因为我不知道在运行时可能需要创建哪种类型的子事件实例,所以我从“event”类扩展了两个子类,并创建了一个父类实例。我的问题是,我是否可以将“Event”类的实例作为参数传递,该参数将在运行时解析为多态函数的一个子类

public void update(Event1);
public void update(Event2);
这是我的密码

public void myFunc(){

    String qualifiedName = new String("events.Event1"); // Event1 info is actually obtained at runtime. 

    Class cls = Class.forName(qualifiedName);
    Event baseEvent = (Event) cls.getDeclaredConstructor().newInstance(); 
    // I want to create an instance like, Event ev1 = new Event1(); and pass it as a parameter.

    observer.update(baseEvent);  // I get compile time error because no update method takes `Event` class instance as parameter.
}
包含多态函数的观察者类

public void update(Event1);
public void update(Event2);
Java泛型在这里有帮助吗?谢谢。

试试这个:

    Method method = observer.getClass().getDeclaredMethod("update", baseEvent.getClass());
    method.invoke(observer, baseEvent);
试试这个:

    Method method = observer.getClass().getDeclaredMethod("update", baseEvent.getClass());
    method.invoke(observer, baseEvent);
试试这个:

    Method method = observer.getClass().getDeclaredMethod("update", baseEvent.getClass());
    method.invoke(observer, baseEvent);
试试这个:

    Method method = observer.getClass().getDeclaredMethod("update", baseEvent.getClass());
    method.invoke(observer, baseEvent);

首先是一些术语:如果在同一类/接口中有一个名称相同但参数不同的方法,如下所示:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
它被称为重载,而不是多态。(很高兴知道你是否想用谷歌搜索这个话题)

第二,回答您的问题:不,Java多态性不适用于此。如果像这样调用上一个更新方法:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
编译器将无法决定调用哪个重载版本的
update()
,因为Java polymorhism不适用于重载方法

您可以尝试对其进行强制转换,以查看其实际类型:

try {
    update((Event1) e);
} catch(ClassCastException ex) {
    //do nothing
}
try {
    update((Event2) e);
} catch(ClassCastException ex) {
    //do nothing
}

现在,如果
e
实际上是
Event1
Event2
,将调用适当的方法。但这需要在编译时了解
事件的所有子类(除非您想弄脏一点并使用反射)。

首先要了解一些术语:如果在同一类/接口中有一个名称相同但参数不同的方法,如下所示:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
它被称为重载,而不是多态。(很高兴知道你是否想用谷歌搜索这个话题)

第二,回答您的问题:不,Java多态性不适用于此。如果像这样调用上一个更新方法:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
编译器将无法决定调用哪个重载版本的
update()
,因为Java polymorhism不适用于重载方法

您可以尝试对其进行强制转换,以查看其实际类型:

try {
    update((Event1) e);
} catch(ClassCastException ex) {
    //do nothing
}
try {
    update((Event2) e);
} catch(ClassCastException ex) {
    //do nothing
}

现在,如果
e
实际上是
Event1
Event2
,将调用适当的方法。但这需要在编译时了解
事件的所有子类(除非您想弄脏一点并使用反射)。

首先要了解一些术语:如果在同一类/接口中有一个名称相同但参数不同的方法,如下所示:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
它被称为重载,而不是多态。(很高兴知道你是否想用谷歌搜索这个话题)

第二,回答您的问题:不,Java多态性不适用于此。如果像这样调用上一个更新方法:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
编译器将无法决定调用哪个重载版本的
update()
,因为Java polymorhism不适用于重载方法

您可以尝试对其进行强制转换,以查看其实际类型:

try {
    update((Event1) e);
} catch(ClassCastException ex) {
    //do nothing
}
try {
    update((Event2) e);
} catch(ClassCastException ex) {
    //do nothing
}

现在,如果
e
实际上是
Event1
Event2
,将调用适当的方法。但这需要在编译时了解
事件的所有子类(除非您想弄脏一点并使用反射)。

首先要了解一些术语:如果在同一类/接口中有一个名称相同但参数不同的方法,如下所示:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
它被称为重载,而不是多态。(很高兴知道你是否想用谷歌搜索这个话题)

第二,回答您的问题:不,Java多态性不适用于此。如果像这样调用上一个更新方法:

public void update(Event1 e);
public void update(Event2 e);
Event e = //get Event from anywhere
update(e);
编译器将无法决定调用哪个重载版本的
update()
,因为Java polymorhism不适用于重载方法

您可以尝试对其进行强制转换,以查看其实际类型:

try {
    update((Event1) e);
} catch(ClassCastException ex) {
    //do nothing
}
try {
    update((Event2) e);
} catch(ClassCastException ex) {
    //do nothing
}

现在,如果
e
实际上是
Event1
Event2
,将调用适当的方法。但这需要在编译时知道
事件的所有子类(除非您想弄脏一点并使用反射)。

顺便说一下。。我更喜欢这种方法(避免反思):


顺便说一下,
Map。。我更喜欢这种方法(避免反思):


顺便说一下,
Map。。我更喜欢这种方法(避免反思):


顺便说一下,
Map。。我更喜欢这种方法(避免反思):


Map您需要使用反射来找到正确的方法来调用您所拥有的事件类型。我认为您可以使用反射来不依赖反射,除非您有特定的规则或只需要使用反射。我想,factory方法也会给我一个父类,在运行时解析,比如Shape Shape=factory.getShape(“Car”);虽然它会在运行时返回一个Car实例,但在编译时,我将有一个父类实例。如果我错了,请纠正我。使用反射来调用方法似乎是可行的。我将尝试一下。您将得到相同的结果:对子类的对象引用,但超类的类型。不同之处在于实现、维护和代码可读性。由您决定使用哪一种,但我建议您使用factory模式,因为它比使用反射更易于理解和维护。您需要使用反射来找到正确的方法来调用您拥有的事件类型。我认为您可能不依赖反射,除非您有特定的规则或只需要使用反射。我猜,工厂方法还将给我一个父类,在运行时解析,比如Shape=factory.getShape(“Car”);虽然它会在运行时返回一个Car实例,但在编译时,我将有一个父类实例。如果我是,请纠正我