如何强制在抽象类的所有子类中定义构造函数

2022-08-31 14:02:52

我有一个定义抽象方法的抽象类A。这意味着,要使类具有可实例化性,必须实现所有抽象方法。

我希望我所有的子类都实现一个具有2 ints作为参数的构造函数。

声明构造函数违背了我的目的,因为我希望在子类中定义构造函数,而我对实现一无所知。此外,我不能将构造函数声明为抽象的;

有没有办法做到这一点?

我想要的例子:

假设我正在定义矩阵类的API。在我的问题中,Matrix无法改变它们的尺寸。

对于要创建的矩阵,我需要提供其大小。

因此,我希望我的所有实现器都为构造函数提供大小作为参数。此构造函数的动机是问题,而不是实现问题。实现可以使用这些操作,前提是保留所有方法的语义。

假设我想在我的抽象类中提供该方法的基本实现。此方法将创建一个具有倒排维度的新矩阵。更具体地说,由于它是在抽象类中定义的,它将使用采用两个 int 的构造函数创建与 相同类的新实例。由于它不知道实例,它将使用反射(getDefinedConstructor),我想要一种方法来警告我会得到它,并且它对实现是有意义的。invert()thisthis


答案 1

你不能在子类中强制构造函数的特定签名 - 但你可以强制它通过抽象类中的构造函数,取两个整数。例如,子类可以从无参数构造函数调用该构造函数,例如传入常量。这是你能来的最接近的。

此外,正如你所说,你对实现一无所知 - 那么你怎么知道他们有一个需要两个整数的构造函数是合适的呢?如果其中一个也需要字符串怎么办?或者,对于其中一个整数使用常量可能是有意义的。

这里更大的图景是什么 - 为什么要在子类上强制使用特定的构造函数签名?(正如我所说,你实际上不能这样做,但如果你解释为什么你想要它,一个解决方案可能会出现。

一种选择是为工厂提供一个单独的接口:

interface MyClassFactory
{
    MyClass newInstance(int x, int y);
}

然后,你的每个具体子类也需要一个工厂,它知道如何在给定两个整数的情况下构建一个实例。不过,这并不是很方便 - 你仍然需要构建工厂本身的实例。再说一遍,这里的真实情况是什么?MyClass


答案 2

你可以尝试下面这样的东西。如果实现类没有具有适当参数的构造函数,则构造函数将引发异常。

这是愚蠢的。比较“确定”和“不好”。这两个类是相同的,只是 OK 满足您的要求,因此通过了运行时检查。因此,强制执行该要求会促进适得其反的繁忙工作。

更好的解决方案是某种工厂。

abstract class RequiresConstructor
{
    RequiresConstructor( int x, int y ) throws NoSuchMethodException
    {
    super();
    System.out.println( this.getClass().getName() ) ;
    this.getClass(). getConstructor ( int.class , int.class ) ;
    }

    public static void main( String[] args ) throws NoSuchMethodException
    {
    Good good = new Good ( 0, 0 );
    OK ok = new OK ();
    Bad bad = new Bad ();
    }
}

class Good extends RequiresConstructor
{
    public Good( int x, int y ) throws NoSuchMethodException
    {
    super( x, y ) ;
    }
}

class OK extends RequiresConstructor
{
    public OK( int x, int y ) throws NoSuchMethodException
    {
    super( x, y ) ;
    throw new NoSuchMethodException() ;
    }

    public OK() throws NoSuchMethodException
    {
    super( 0, 0 ) ;
    }
}

class Bad extends RequiresConstructor
{
    public Bad() throws NoSuchMethodException
    {
    super( 0, 0 ) ;
    }
}