You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

面试题:能否用单个对象调用父类及不同子类的方法?

能否用单个对象调用A、B、C三个类的任意方法?

当然可以实现!虽然B和C作为A的子类,互相没有对方的属性和方法,但咱们可以通过两种靠谱的方式,搞出一个「统一入口」的对象,让它能调用这三个类的所有方法。下面给你详细讲讲:

方法一:组合(委托)模式(最推荐)

这是最直观也最易维护的方案——创建一个新类,把A、B、C的实例都作为它的成员变量,然后在这个新类里封装对应方法,内部委托给对应的实例去执行。

先给三个类加些具体方法方便演示:

class A {
    public void methodA() {
        System.out.println("调用了A类的方法");
    }
}

class B extends A {
    public void methodB() {
        System.out.println("调用了B类的方法");
    }
}

class C extends A {
    public void methodC() {
        System.out.println("调用了C类的方法");
    }
}

然后写这个统一入口类:

class UnifiedCaller {
    private A aInstance = new A();
    private B bInstance = new B();
    private C cInstance = new C();

    // 委托调用A的方法
    public void methodA() {
        aInstance.methodA();
    }

    // 委托调用B的方法
    public void methodB() {
        bInstance.methodB();
    }

    // 委托调用C的方法
    public void methodC() {
        cInstance.methodC();
    }

    // 如果B重写了A的方法,还可以单独提供调用B版本的入口
    public void methodAFromB() {
        bInstance.methodA();
    }
}

使用的时候超简单,一个对象搞定所有调用:

public class Main {
    public static void main(String[] args) {
        UnifiedCaller caller = new UnifiedCaller();
        caller.methodA();   // 调用A的方法
        caller.methodB();   // 调用B的方法
        caller.methodC();   // 调用C的方法
    }
}

这种方式的好处是类型安全,编译期就能发现错误,而且逻辑清晰,后续维护起来也省心。

方法二:反射(灵活但不推荐)

如果三个类的方法特别多,手动写委托代码嫌麻烦,也可以用反射来实现。不过这种方式类型不安全,只有运行时才会发现方法名写错、参数不匹配的问题,所以只适合临时场景或者特殊需求。

我们可以写一个通用调用类,内部持有三个类的实例,通过反射自动找对应方法执行:

import java.lang.reflect.Method;

class ReflectiveCaller {
    private A a = new A();
    private B b = new B();
    private C c = new C();

    public void callMethod(String methodName, Object... args) throws Exception {
        // 优先找B类的方法
        try {
            Method method = B.class.getMethod(methodName, getParamTypes(args));
            method.invoke(b, args);
            return;
        } catch (NoSuchMethodException e) {
            // 找不到就找C类的方法
            try {
                Method method = C.class.getMethod(methodName, getParamTypes(args));
                method.invoke(c, args);
                return;
            } catch (NoSuchMethodException ex) {
                // 最后找A类的方法
                Method method = A.class.getMethod(methodName, getParamTypes(args));
                method.invoke(a, args);
            }
        }
    }

    // 辅助方法:获取参数的类型数组
    private Class<?>[] getParamTypes(Object[] args) {
        if (args == null || args.length == 0) {
            return new Class[0];
        }
        Class<?>[] types = new Class[args.length];
        for (int i = 0; i < args.length; i++) {
            types[i] = args[i].getClass();
        }
        return types;
    }
}

使用方式如下:

public class Main {
    public static void main(String[] args) throws Exception {
        ReflectiveCaller caller = new ReflectiveCaller();
        caller.callMethod("methodA");
        caller.callMethod("methodB");
        caller.callMethod("methodC");
    }
}

总结

  • 优先选组合(委托)模式,安全、清晰、易维护,是日常开发的最佳实践;
  • 反射方式只适合特殊场景,不建议在正式项目中大量使用;
  • 至于动态代理,更适合接口而非类的场景,对于你这种类继承的情况,组合模式是最稳妥的选择。

内容的提问来源于stack exchange,提问作者Rajat Sangrame

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.28 09:31:18