Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allowing implementing interface only for specific classes

Is it possible to permit only some specific classes to implement an iterface? Let's say that I created interface IMyInterface and I want only classes which derive from UserControl to have an ability to implement my interface. Is this possible?

like image 612
tron Avatar asked Apr 23 '11 21:04

tron


People also ask

Can an interface be implemented by multiple classes?

Yes an interface can be implemented by multiple classes.

Do I need to use an interface when only one class will ever implement it?

Interfaces can be implemented by multiple classes. There is no rule that only one class can implement these. Interfaces provide abstraction to the java.

Do classes have to implement all interface methods?

Yes, it is mandatory to implement all the methods in a class that implements an interface until and unless that class is declared as an abstract class.

How do you restrict an interface in Java?

The only option I see is to make the interface package-private and implement it by public SuperClass which is located in the same package. This way the users of your package will be able to subclass the SuperClass , but not able to implement your interface directly.


2 Answers

You cannot, but you can achieve something similar by adding a Control property to your interface, and by-convention making all the implementations return this. Doesn't solve your problem, but makes the implementer think a bit whether or not the interface really belongs there. Also allows the user of the interface to retrieve the control in a type-safe manner without casting.

interface IMyInterface
{
    void Foo();
    UserControl Control { get; }
}


class MyControl : UserControl, IMyInterface
{
    public void Foo()
    {
        // TODO: Write code here
    }

    UserControl IMyInterface.Control
    {
        get { return this; }
    }
}

UPDATE

There is also another solution - making a generic method. The interface itself will not be restricted, but the method operating will be. For example, the following method requires that its parameter both inherits UserControl and implements IMyInterface:

void Bar<T>(T item)
  where T : UserControl, IMyInterface
{
    item.Width = 120;    // user control property
    item.Foo();          // IMyInterface method
}
like image 73
Alex Shtof Avatar answered Sep 23 '22 05:09

Alex Shtof


I realize this is an old post, but I had to solve exactly this problem.

Here is how you can do it:

class BaseClass { }

interface OnlyBaseClass<TSelf> where TSelf : BaseClass, OnlyBaseClass<TSelf>
{

}

class ChildClass : BaseClass, OnlyBaseClass<ChildClass> { }

class ImpostorClass : OnlyBaseClass<ImposterClass> { }

interface ImposterInterface : OnlyBaseClass<ImposterInterface > { }

Try to compile the above. You will notice that it doesn't compile (due to the two impostors, one a class, one an interface).

The constraint on TSelf can be understood as:

TSelf must: Inherit from BaseClass and implement OnlyBaseClass<TSelf>

...which only a type inheriting from BaseClass and implementing OnlyBaseClass could do.

You could be clever, and do the following:

class AdvancedImpostorClass : OnlyBaseClass<ChildClass> {}

... which will compile. You could prevent these types of impostors from ever getting through into your code by using the same constraints in any methods that accept them as arguments though, like so:

public SomeMethod<TBaseAndInterface>(TBaseAndInterface value)
    where TBaseAndInterface: BaseClass, OnlyBaseClass<TBaseAndInterface>
{ }

This is all made possible through the power of F-Bound Polymorphism.

like image 31
shockwave121 Avatar answered Sep 23 '22 05:09

shockwave121