interface IXXX
{
void Foo();
}
class XXX : IXXX
{
public static void Foo()
{
Console.WriteLine("From XXX");
}
}
class Program
{
static void Main(string[] args)
{
XXX.Foo();
}
}
Compiler error: XXX.Foo() cannot implement an interface member because it is static.
Why can't a static method implement an interface method?
See this thread from JoelOnSoftware describing the reasons behind this.
Basically the interface is the contract between the consumer and the provider, and a static method belongs to the class, and not each instance of the class as such.
An earlier question on SO also deal with the exact same question:
Why Doesn't C# Allow Static Methods to Implement an Interface?
An interface defines the behaviour that an object must respond to.
As Foo is a static method, the object doesn't respond to it. In other words, you couldn't write...
XXX myXXX = new XXX();
myXXX.Foo();
In other words, myXXX doesn't fully satisfy the requirements of the interface.
IF we look at interfaces as a promise that an object can perform the methods listed in the interface, then ths idea of static implementation becomes problematic. If the implemetion is static, then you can't write new ImplementingObject().ImplementedMthod. The object can't perform the method, the class can.
You use interface to avoid using concrete class during instantiation. You can't access static method through instantiated class, so implementing interface methods with static methods is not allowed.
Well, I believe it should allowed in case of generic type parameter. It probably simplified contractual singleton class. Here is an example:
public interface IEntity {
// some constrains...
DataRow ObjToRow(object obj);
object RowToObj(DataRow dr);
}
//T would be any class inherites from IEntity with default contructor signature.
public interface IMyContract {
T read<T>() where T : IEntity;
void write<T>(T object) where T : IEntity;
}
//everything in the class is static
public static class SqlProvider : IMyContract {
public static T read<T>() where T: IEntity {
DataRow dr = [reading from database]
return T.RowToObj(dr);
}
//compile error here....
public static void write<T>(T obj) where T : IEntity {
DataRow dr = T.ObjToRow(obj);
[ ... commit data row dr to database ... ]
}
}
public static class MyAppleEntity : IEntity {
[... implement IEntity contract normally ... ]
}
public static class MyOrangeEntity : IEntity {
[... implement IEntity contract normally ... ]
}
public class MyTest {
void reading() {
MyAppleEntity apple = SqlProvider.Read<MyAppleEntity>();
MyOrangeEntity orange = SqlProvider.Read<MyOrangeEntity>();
SqlProvider.write<MyAppleEntity>(apple);
SqlProvider.write<MyOrangeEntity>(orange);
}
}
The only time a type reference implicitly is in the SqlProvider.read() and write() and T is well identity at point of invoke. Without static implementation of interface I'm forced to write like this.
public class MyAppleEntity : IEntity {
[... implement IEntity contract normally ... ]
}
.....
public T read<T>() where T: IEntity, new() {
DataRow dr = [reading from database]
return new T().RowToObj(dr);
}
Very little different but not quite as elegant.
Because interface member are public and overridable, and that static method cannot by design be overrided or abstract, Interfaces are here to define an accessible contract that must be implemented by their concrete implementation (with as many steps of abstract implementations & inherited interfaces between) and as far as I know there is no way to create an abstract static method.
Related
In the following sample class "SomeClass" does not implement "ISomeInterface". Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
namespace Test
{
public interface IBaseInterface
{
void DoBaseStuff();
}
public interface IChildInterface : IBaseInterface
{
void DoChildStuff();
}
public interface ISomeInterface
{
void DoSomething(IBaseInterface baseInterface);
}
public class SomeClass : ISomeInterface
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
}
This restriction exists because the ISomeInterface expects that any IBaseInterface will satisfy the contract. That is, if you have the following:
public interface IBase {}
public interface IChildA : IBase {}
public interface IChildB : IBase {}
And an interface that expects IBase:
public interface IFoo { void Bar(IBase val); }
Then restricting this in a derived class as you would like:
public class Foo : IFoo { public void Bar(IChildA val) {} }
Would create the following problem:
IChildB something = new ChildB();
IFoo something = new Foo();
something.Bar(something); // This is an invalid call
As such, you're not implementing the contract you said you would.
In this situation, you have two simple options:
Adjust IFoo to be generic, and accept a T that is a derivation of IBase:
public interface IFoo<T> where T : IBase { void Bar(T val); }
public class Foo : IFoo<IChildA> { public void Bar(IChildA val) {} }
Of course, this means that Foo can no longer accept any IBase (including IChildB).
Adjust Foo to implement IFoo, with an additional utility method for void Bar(IChildA val):
public class Foo : IFoo
{
public void Bar(IBase val) {}
public void Bar(IChildA val) {}
}
This has an interesting side-effect: whenever you call ((IFoo)foo).Bar it will expect IBase, and when you call foo.Bar it will expect IChildA or IBase. This means it satisfies the contract, while also having your derived-interface-specific method. If you want to "hide" the Bar(IBase) method more, you could implement IFoo explicitly:
void IFoo.Bar(IBase val) { }
This creates even more inconsistent behavior in your code, as now ((IFoo)foo).Bar is completely different from foo.Bar, but I leave the decision up to you.
This means, with the second version in this section, that foo.Bar(new ChildB()); is now invalid, as IChildB is not an IChildA.
Why can't I implement this by passing a more derived interface which does implement the base requirement. Whatever instance would be passed it would still implement the base, am I missing something?
This is not allowed because of the reasoning I mentioned above, IFoo.Bar expects any IBase, whereas you want to further constrain the type to IChildA, which is not a super-interface of IBase, and even if it were it would not be allowed because it violates the interface implementation, though you could more easily define a second method at that point that does what you want.
Keep in mind that when you implement an interface, you subscribe to a contract, and C# will not let you violate that contract.
This violates the Liskov substitution principle.
ISomeInterface guarantees that the method can be called with any IBaseInterface instance. Your implementation cannot limit that to only accept IChildInterface interfaces.
From MSDN:
When a class or struct implements an interface, the class or struct must provide an implementation for all of the members that the interface defines
This method in the derived
void DoSomething(IChildInterface baseInterface)
Does not have the same signature as the one in the interface:
void DoSomething(IBaseInterface baseInterface)
IChildInterface and IBaseInterface are not the same types. Therefore your derived class does not implement all methods of the interface and you get the compilation error.
For a possible the logic behind having this as a restriction instead of the compiler understanding the inheritance see Liskov's substitution principle as in SLakes answer
You should change some interface to use some type which implements IBaseInterface,
then change the method signatures to use whichever child your SomeClass wants.
public interface ISomeInterface<TSomeChild> where TSomeChild : IBaseInterface
{
void DoSomething(TSomeChild baseInterface);
}
public class SomeClass : ISomeInterface<IChildInterface>
{
public void DoSomething(IChildInterface baseInterface)
{
}
}
If you could do that, then you could do this:
IAnimal cat = new Cat();
IAnimalTrainer dogTrainer = new DogTrainer();
dogTrainer.Train(cat);
An IAnimalTrainer can train any IAnimal. But a DogTrainer can only train Dogs. Thus it's illegal for DogTrainer to implement the IAnimalTrainer interface.
SqlDataReader's class statement includes IDataReader, IDataRecord and IDisposable even though these are all implemented by its base class, DbDataReader:
public class SqlDataReader : DbDataReader,
IDataReader, IDisposable, IDataRecord {...}
public abstract class DbDataReader : MarshalByRefObject,
IDataReader, IDisposable, IDataRecord, IEnumerable {...}
In this case, is there some technical advantage to indicating that the derived class implements interfaces which its base class already indicates that it implements? (I can't think of one. Wondering if this is a legacy relic, a typo or something done for documentation purposes.)
This could be done in order to add or override explicit interface implementations in the derived class. For example,
interface IFoo
{
string P {get;}
}
class Base: IFoo
{
string IFoo.P
{
get { return "Base"; }
}
}
class Derived: Base, IFoo
{
string IFoo.P
{
get { return "Derived"; }
}
}
If Derived doesn't implement IFoo directly, it cannot define an explicit implementation of IFoo.P, so it cannot override the implementation in the base class.
This makes sense if you want to implement some interface explicitly.
For example:
interface ISome
{
void Method();
}
class A : ISome
{
public void Method()
{
}
}
class B : A, ISome // Try to remove ISome...
{
void ISome.Method()
{
}
}
If you comment out the ISome in the B declaration, compilation will fail.
I have the following .
public interface IMyService<T>
where T: BaseModelType
{
Process(T input);
}
public class BaseModelType
{
...some property
}
public class SomeClass : BaseModelType
{
...some properties
}
public ServiceImpl : IMyService<SomeClass>
{
...the properties
}
Then I have a unity container where i register all the implementations of the generic interface. I want to be able to use the unitycontainer's resolve method to get the interface, then do some work on it. At the time when i want to use the Resolve method i have the type in runtime
new UnityContainer.Resolve(myTypeVar)
Can I somehow cast this to be
IMyService<BaseModelType> value = new UnityContainer.Resolve(myTypeVar) //want to cast it here from object.
So that i can call the Process method that the interface defines.
No, because IMyService<SomeClass> does not implement IMyService<BaseModelType>. If you look at the implementation of the Process method:
public void Process(SomeClass input){...}
This clearly assumes that you're giving it a SomeClass. It should be able to safely access any members of SomeClass. But if you called this method with a BaseModelType as the parameter, that wouldn't work, would it?
Assuming that you know at runtime that your input argument is going to be of the right type for the given generic IMyService<T> interface, you have two options:
Invoke the generic method signature via reflection. A little slow, but effective.
Add a non-generic parent interface for IMyService, which takes a BaseModelType. In your service implementations, you can implement this method by casting the input to the expected type for that implementation. This requires more code. But you could alleviate that somewhat by having a generic abstract base class that implements this method so the other implementations don't have to.
void Main()
{
var s = (IMyService)new ServiceImpl();
s.Process(new SomeClass());
}
public interface IMyService
{
void Process(BaseModelType input);
}
public interface IMyService<in T> : IMyService
where T: BaseModelType
{
void Process(T input);
}
public class BaseModelType{}
public class SomeClass : BaseModelType{}
public abstract class ServiceBase<T> : IMyService<T>
where T: BaseModelType
{
void IMyService.Process(BaseModelType input)
{
Process((T)input);
}
public abstract void Process(T input);
}
public class ServiceImpl : ServiceBase<SomeClass>{
public override void Process(SomeClass input){}
}
I am trying to port some code I wrote in C# to Java, but do not know all of the Java syntax yet. I also have no idea what this type of thing is called, so it is harder to search..I am calling it "inheritance constraints."
Basically, is there a java equivalent to this C# code:
public abstract class MyObj<T> where T : MyObj<T>, new()
{
}
Thanks.
Edit:
Is there any way to do this:
public abstract class MyObj<T extends MyObj<T>> {
public abstract String GetName();
public virtual void Test() {
T t = new T(); // Somehow instantiate T to call GetName()?
String name = t.GetName();
}
}
Not quite. There's this:
public abstract class MyObj<T extends MyObj<T>>
but there's no equivalent to the new() constraint.
EDIT: To create an instance of T, you'll need the appropriate Class<T> - otherwise type erasure will byte you.
Typically you'd add this as a constructor parameter:
public MyObj(Class<T> clazz) {
// This can throw all kinds of things, which you need to catch here or
// propagate.
T t = clazz.newInstance();
}
Judging by your comment above, you're looking for the following construct:
An interface with which you will interact with MyObj objects in code... you will be calling the test() method (standard style in Java is camelcase methods, capitalized classes/interfaces)
public interface IMyObj {
public void test();
}
You will want the abstract superclass... for the example that you've chosen, you don't NEED to specify any genericism, although you absolutely can if the actual implementation is more reliant on type safety... this class should implement the IMyObj interface:
public abstract class MyObj implements IMyObj {
String name;
public abstract String getName();
public void test() {
name = getName();
}
}
From here you would write your subclasses to MyObj...
public class MySubObj1 extends MyObj {
public String getName() { return "MySubObj1"; }
}
public class MySubObj2 extends MyObj {
public String getName() { return "MySubObj2"; }
}
Then you safely and correctly use the following snippet in another class:
IMyObj obj = new MySubObj1();
obj.test();
The key is that you use interfaces to hide the implementation, and use abstract classes to hold common code that subclasses will utilize in their implementations.
Hope this helps!
I'm learning C# coming from C++ and have run into a wall.
I have an abstract class AbstractWidget, an interface IDoesCoolThings, and a class which derives from AbstractWidget called RealWidget:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget : IDoesCoolThings
{
void IDoesCoolThings.DoCool()
{
Console.Write("I did something cool.");
}
}
public class RealWidget : AbstractWidget
{
}
When I instantiate a RealWidget object and call DoCool() on it, the compiler gives me an error saying
'RealWidget' does not contain a
definition for 'DoCool'
I can cast RealWidget object to an IDoesCoolThings and then the call will work, but that seems unnecessary and I also lose polymorphism (AbstractWidget.DoCool() will always be called even if i define RealWidget.DoCool()).
I imagine the solution is simple, but I've tried a variety of things and for the life of me can't figure this one out.
You're running into the issue because you used explicit interface implementation (EII). When a member is explicitly implemented, it can't be accessed through a class instance -- only through an instance of the interface. In your example, that's why you can't call DoCool() unless you cast your instance to IDoesCoolThings.
The solution is to make DoCool() public and remove the explicit interface implementation:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool() // DoCool() is part of the abstract class implementation.
{
Console.Write("I did something cool.");
}
}
// ...
var rw = new RealWidget();
rw.DoCool(); // Works!
In general, you use EII in two cases:
You have a class that must implement two interfaces, each of which contains a member that has an identical name/signature to another member in the other interface.
You want to force clients not to depend on the implementation details of your class, but rather on the interface that's being implemented by your class. (This is considered a good practice by some.)
The way you implement the interface is explicit implement void IDoesCoolThings.DoCool(), if you choose implicit implement interface.
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
Then it will work.
Read this :
C# Interfaces. Implicit implementation versus Explicit implementation
Change your declaration to:
public abstract class AbstractWidget : IDoesCoolThings
{
public void DoCool()
{
Console.Write("I did something cool.");
}
}
You should do it this way:
public interface IDoesCoolThings
{
void DoCool();
}
public abstract class AbstractWidget
{
public void DoCool()
{
Console.WriteLine("I did something cool.");
}
}
public class Widget : AbstractWidget, IDoesCoolThings
{
}
Usage:
var widget = new Widget();
widget.DoCool();