【问题标题】:Is it possible to "adopt" a class as a child?小时候可以“收养”一个班级吗?
【发布时间】:2021-05-18 21:00:38
【问题描述】:

我目前正在编写一个类,它应该作为现有类的附加组件。例如,让我的附加类如下:

public class NewClass {}

另外,假设已经存在如下类:

public final class ExistingClassA {}
public final class ExistingClassB {}
...

这些我不允许更改。 不过,对于某些算法,我想将现有类定义为我的NewClass 的子类。因此,我不想使用extends 从某个类继承,而是想要实现相反的效果:我想“采用”一个类,就好像现有的类最初是这样定义的:

public final class ExistingClassA extends NewClass {}
public final class ExistingClassB extends NewClass {}
...

这在 Java 中是否可行?如果是这样,是否也可以添加一个类作为已经扩展另一个类的类的父类?

编辑:

为了让我的情况更清楚一点,我将尝试更详细地描述我想要实现的目标。例如。假设一个变量myVar,它应该只是特定类的实例。如果这些类属于一个共同的父类,这不会是一个问题:

public final class ExistingClassA extends CommonParentClass {}
public final class ExisitingClassB extends CommonParentClass {}
public final class ExistingClassC extends CommonParentClass {}

...
/* We're inside some class now... */
CommonParentClass myVar; // May be of ExistingClassA, ExistingClassB, or ExistingClassC.

现在说,我希望 myVar 仅属于 ExistingClassAExistingClassB 类。假设我可以用我的NewClass“采用”这两个类,我也可以写:

NewClass myVar; // May be of ExistingClassA, or ExistingClassB, but not ExistingClassC.

既然这似乎是可能的(从阅读 cmets),什么方法是最聪明的方法来实现只允许myVar 成为CommonParentClass 的一个子集的目标?

【问题讨论】:

  • Java 中没有机制可以做到这一点,除非您使用反射进行高度复杂的操作。一种简单的方法是创建一个代理来公开现有类和新类的功能。
  • 有趣。这可以通过哪些语言实现?
  • 我很好奇这是干什么用的?这感觉就像您在脑海中开发一个解决方案并询问如何实施该解决方案而不是询问问题。
  • @JimGarrison 听起来很有趣!您能否再解释一下或提供进一步阅读的链接?
  • @MatthewKerian 我对我的目标添加了一些进一步的解释。

标签: java inheritance subclass extends


【解决方案1】:

没有编译时机制来检查一个类是扩展了 A 类还是 B 类。如果 AB 的作者没有定义它们是相关的,那么它们就不是。

您有多种选择:

  • 您可以使用 instanceof 然后强制转换为指定的类型。

    Object myObj = ...;
    if (myObj instanceof Alpha) {
        ((Alpha) myObj).doSomething();
    }
    else if (myObj instanceof Bravo) {
        ((Bravo) myObj).doSomethingElse();
    }
    else {
        throw new IllegalArgumentException("myObj" must be of either Alpha or Bravo");
    }
    
  • 或者您可以在构造函数中创建一个接受任一包装器对象:

    class Either<A, B> {
        A a;
        B b;
        boolean isA;
        Either(A a) {
            this.a = a;
            this.isA = true;
        }
        Either(B b) {
            this.b = b;
        }
        boolean isA() {
            return isA;
        }
        A getA() {
            return a;
        }
        B getB() {
            return b;
        }
    }
    

    然后调用它:

    Either<Alpha, Bravo> either = new Either(...);
    if (either.isA()) {
        either.getA().doSomething();
    }
    else {
        either.getB().doSomethingElse();
    }
    

但我看不到如何你想使用这两个类。他们有同名的方法吗?为什么不直接使用两个变量?

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-19
    • 2016-01-13
    相关资源
    最近更新 更多