c# How do you force constructor signatures and static methods?




class constructor c# (8)

You could use the Factory pattern.

interface Fruit{}

interface FruitFactory<F extends Fruit>{
   F newFruit(String color,double weight);

   Cocktail mixFruits(F f1,F f2);
}

You could then create classes for any type of Fruit

class Apple implements Fruit{}
class AppleFactory implements FruitFactory<Apple>{
   public Apple newFruit(String color, double weight){
       // create an instance
   }
   public Cocktail mixFruits(Apple f1,Apple f2){
       // implementation
   }
}

This does not enforce that you can't create instance in another way than by using the Factory but at least you can specify which methods you would request from a Factory.

Is there a way of forcing a (child) class to have constructors with particular signatures or particular static methods in C# or Java?

You can't obviously use interfaces for this, and I know that it will have a limited usage. One instance in which I do find it useful is when you want to enforce some design guideline, for example:

Exceptions
They should all have the four canonical constructors, but there is no way to enforce it. You have to rely on a tool like FxCop (C# case) to catch these.

Operators
There is no contract that specifies that two classes can be summed (with operator+ in C#)

Is there any design pattern to work around this limitation? What construct could be added to the language to overcome this limitation in future versions of C# or Java?


You could use the Factory pattern.

interface Fruit{}

interface FruitFactory<F extends Fruit>{
   F newFruit(String color,double weight);

   Cocktail mixFruits(F f1,F f2);
}

You could then create classes for any type of Fruit

class Apple implements Fruit{}
class AppleFactory implements FruitFactory<Apple>{
   public Apple newFruit(String color, double weight){
       // create an instance
   }
   public Cocktail mixFruits(Apple f1,Apple f2){
       // implementation
   }
}

This does not enforce that you can't create instance in another way than by using the Factory but at least you can specify which methods you would request from a Factory.


How do you force constructor signatures and static methods?

Not enforced at compile-time, but I have spent a lot of time looking at similar issues; a generic-enabled maths library, and an efficient (non-default) ctor API are both avaiable in MiscUtil. However, these are only checked at first-usage at runtime. In reality this isn't a big problem - your unit tests should find any missing operator / ctor very quickly. But it works, and very quickly...


How to enforce constructor in Java

There are no facilities in Java to do that directly.

However, it can be enforced to some extent usin an abstract method.

abstract class Base {

    Base(String s1, String s2) {
        init(s1, s2);
    }

    protected abstract void init(String s1, String s2);
}

class MyClass extends Base {

    // Forced to do this.
    MyClass() {
        super("One", "Two");
    }

    // Forced to do this.
    @Override
    protected void init(String s1, String s2) {
    }

}

Sorry, but no, you cannot force classes to only implement a specific constructor.


Using generics you can force a type argument to have a parameterless constructor - but that's about the limit of it.

Other than in generics, it would be tricky to actually use these restrictions even if they existed, but it could sometimes be useful for type parameters/arguments. Allowing static members in interfaces (or possibly static interfaces) could likewise help with the "generic numeric operator" issue.

I wrote about this a little while ago when facing a similar problem.


You want that there is only one constructor, and that with the same signature. That could in a costly way done with reflection, at run-time.

public BaseClass(String s, String t, int n) {
    Class<?> cl = getClass();
    do {
        check(cl);
        cl = cl.getSuperclass();
    } while (cl != BaseClass.class);
}

private void check(Class<?> cl) {
    if (cl.getConstructors().length != 1) {
        throw new IllegalStateException("Needs only 1 constructor in: " + cl.getName());
    }
    try {
        cl.getConstructor(String.class, String.class, int.class);
    } catch (NoSuchMethodException e) {
        throw new IllegalStateException("Constructor should have parameter types (String, String, int) in: " + cl.getName());
    }
}

Not advisable

However you could make a factory to be used that hides class hierarchies. Or in fact use a single class that delegates to your class hierarchy (has a member of your class).


Not enforced at compile-time, but I have spent a lot of time looking at similar issues; a generic-enabled maths library, and an efficient (non-default) ctor API are both avaiable in MiscUtil. However, these are only checked at first-usage at runtime. In reality this isn't a big problem - your unit tests should find any missing operator / ctor very quickly. But it works, and very quickly...







language-design