I have an interface:
interface IFoo {
int foo(int bar);
}
Can I now extend an existing class to conform to the interface? Say class String. I know I can define the foo() method on strings. But is it possible to go further and tell the compiler that strings can be cast to IFoo?
You can do it with other classes, but not with System.String, because it is sealed.
If you wanted to do this to a non-sealed class, you could simply derive from it, add appropriate constructors, and put the interface as something that your new class implements.
interface IFoo {
int Size {get;}
}
// This class already does what you need, but does not implement
// your interface of interest
class OldClass {
int Size {get;private set;}
public OldClass(int size) { Size = size; }
}
// Derive from the existing class, and implement the interface
class NewClass : OldClass, IFoo {
public NewCLass(int size) : base(size) {}
}
When the class is sealed, your only solution of presenting it as some interface through composition: write a wrapper class implementing your interface, give it an instance of the sealed class, and write method implementations that "forward" calls to the wrapped instance of the target class.
I think the question could be restated as, 'can I use extension methods to make a sealed class implement an interface that it did not before?' As others point out, the String class is sealed. However, I think you have to name what interfaces a class implements in its declaration:
public someClass : IFoo
{
// code goes here
}
So you can't do this directly to String, not just because it is sealed, but because you do not have the source code for it.
The best you can do is make your own class that has-a String and use it like a string. Anything that a String does that you need to do you will either have to do on its String member (thus making it public), or you will have to wrap/reimplement the method you need:
public class betterString : IFoo
{
public String str {get; set;}
public foo(int i)
{
// implement foo
}
}
then later, when using it:
public void someMethod(betterString better)
{
better.foo(77);
System.Console.WriteLine(better.str);
}
Related
abstract class someClass
{
public abstract IProduct SomeMethod();
}
public interface IProduct
{
string Operation();
}
I have seen the above code having a method define inside abstract class with type interface, I wonder the use of this. Can anybody explain?
You are asking about this:
abstract class SomeBaseClass
{
public abstract IProduct SomeMethod();
}
In this case, IProduct may represent any object that implements the interface, and the method SomeMethod() is guaranteed to return an object of some class implementing IProduct.
This has many uses where the design dictates that all classes that derive from SomeBaseClass be able to create objects that adhere to the IProduct interface.
In c# interfaces are like contracts that guarantee specific behavior and properties.
This means that regardless of the actual implementation, code like this below is valid
SomeBaseClass f = ...
IProduct p = f.SomeMethod();
string op = p.Operation();
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.
I need some sort of way to mark base interfaces and identify if a class implemented the base interface or its derived interface. c# doesn't allow having 'abstract interface'. Is there any way to do this in c#?
public interface IBaseFoo
{
void BaseMethod();
}
public interface IFoo : IBaseFoo
{
void FooMethod();
}
public class Base
{
}
public class A : Base, IFoo
{
}
public class B : Base, IBaseFoo
{
}
Now in the following method I need to check if the typeCls is implemented the IFoo or IBaseFoo without explicitly specifying types. I need sort of a way to mark the base interface and identify it in the method. (ie: if c# allowed having abstract interface, I could have check if IsAbstract property of interfaces of typeClas)
public bool IsBaseFooImplemented<T>(T typeCls) where T : Base
{
// Here I need to check if the typeCls is implemented the IFoo or IBaseFoo
}
Because IFoo : IBaseFoo, every class implementing IFoo also implements IBaseFoo. But not the other way around, so you can simply check whether typeCls is IFoo.
Do note that changing behavior based on implemented interfaces generally is a design smell that bypasses the use for interfaces in the first place.
//somewhere define
static List<IBaseFoo> list = new List<IBaseFoo>();
public class A : Base, IFoo
{
public A()
{
YourClass.list.add(this);
}
}
public class B : Base, IBaseFoo
{
public B()
{
YourClass.list.add(this);
}
}
//then you can check if a class is IFoo or not.
public bool IsBaseFooImplemented<T>(T typeCls) where T : Base
{
foreach(var c in list )
{
if(typeof(c) == typeCls) return true;
}
return false;
}
I have not tested the code but it should work.
This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Interface vs Abstract Class (general OO)
In one of the MSDN article following line is mentioned
Interfaces cannot specify new members in later versions while
abstract classes can add members as needed to support additional
functionality.
I picked this sentence from here. You can read the same sentence in paragraph 3.
I have a confusion, sorry in advance for in case I am missing something.
Once the Abstaract Class or Interface is declared and then any Derived class is inheriting the methods, in either case, all the methods should be overridden. Otherwise compilation error will come.
Your comments?
Once the Abstaract Class or Interface is declared and then any Derived class is inheriting the methods, in either case, all the methods should be overridden. Otherwise compilation error will come.
No, for an abstract class only the abstract methods need to be overridden. You can add non-abstract methods with no errors.
For example, version 1:
public abstract class FooBase
{
public abstract void Bar();
}
public class FooImpl : FooBase
{
public override void Bar() {}
}
Now introduce a new non-abstract method in FooBase for version 2:
public abstract class FooBase
{
public abstract void Bar();
public void NewMethod() {}
}
... and there's no problem.
Note that for company internal code, where all the code which is going to use the API is rebuilt at the same time, this is often not a problem at all, with either interfaces or abstract classes. If you want to add a method to an interface, you can do so as you can upgrade all implementations at the same time.
It's really when you don't have control over the whole code base that you need to be careful.
an class implementing an interface MUST implement all methods and properties defined in the interface.
when inheriting from an Abstract class, you MUST implement/override all the Abstract members, but any non-abstract members will be inherited just as when you inherit from a concrete class.
When you inherit from Interfaces, you must implement all members of that interface. But you can expand on the interface as you deem fit. You can also inherit multiple interfaces. Valid Example:
public interface IPerson
{
string FullName { get; set; }
string SSN { get; set; }
}
public interface IPersonDBContext
{
void Save(IPerson person);
}
public class PersonData : IPerson, IPersonDBContext
{
// Implements IPerson FullName
public string FullName { get; set; }
// Implements IPerson SSN
public string SSN { get; set; }
// Implements IPersonDBContext Save()
public void Save(IPerson person)
{
// Code to save the IPerson instance to the DB...
}
// Added method, not included in any interface...
public void Validate(IPerson person)
{
// Code to validate the IPerson instance...
}
}
Now, for Abstract classes, you can include concrete methods that can be inherited, but also specify some methods that must be overridden. However, note, you cannot have more than one Base Class (and an Abstract Class is still a class...) So you can't mix two abstract classes like you can an interface. Example:
public abstract class Person
{
public string FullName { get; set; }
public string SSN { get; set; }
public abstract void Save();
}
public class PersonData : Person
{
// Implements Abstract Person Save() Method
public override void Save()
{
// Save logic here...
}
// Non-inherited member...
public void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
}
Lastly, and most powerfully, you can mix a single abstract base class with as many interfaces as you want... So, If I kept the Abstract class Person, from example 2, and the Interface IPersonDBContext from example 1, I could do this:
public class PersonData : Person, IPersonDBContext
{
// Implements Abstract Person Save() Method
public override void Validate()
{
// Access properties of the base class (Abstract Person)
this.FullName.ToString();
this.SSN.ToString();
}
// Inplmenets IPersonDBContext Save()
public void Save(Person person)
{
// Save logic here...
}
// Non-inhereted method
public void Clone(Person person)
{
// Logic to make a member-wise clone.
}
}
Hope that helps...
Implementing an interface forces you to override its methods - inheriting a class however gives you a choice. Only abstract methods needs to be overriden. The MSDN excerpt points out that the price of a strict interface contract can prove to be expensive later on, when all implementors will need to implement the added methods. Using a class parent with virtual methods let you decide later on whether you need a specialization.
I am creating an object structure and I want all sub classes of the base to be forced to implement a method.
The only ways I could think of doing it were:
An abstract class - Would work but the base class has some useful helper functions that get used by some of the sub classes.
An interface - If applied to just the base class then the sub classes don't have to implement the function only the base class does.
Is this even possible?
N.B. This is a .NET 2 app.
You can have abstract methods in a class with other methods that are implemented. The advantage over an interface is that you can include some code with your class and have the new object be forced to fill in the details for the abstract methods.
public abstract class YourClass
{
// Your class implementation
public abstract void DoSomething(int x, int y);
public void DoSomethingElse(int a, string b)
{
// You can implement this here
}
}
An abstract class - Would work but the
base class has some useful helper
functions that get used by some of the
sub classe
An abstract class doesn't require all functions it provides to be abstract.
abstract class Base {
public void Foo() {} // Ordinary method
public virtual void Bar() {} // Can be overridden
public abstract void Xyz(); // This one *must* be overridden
}
Note that if you replace public with protected, the marked method will be only visible to base classes and subclasses.
An interface - If applied to just the
base class then the sub classes don't
have to implement the function only
the base class does.
This is not entirely correct. If the base class is abstract, you can mark methods that belong to the interface as abstract, and force the implementation in the subclasses.
That brings an option you didn't mention: to use both. You have an IFoo interface, and a FooBase abstract base class the implements it, or part of it. This provides subclasses with a "default" implementation of the interface (or part of it), and also lets you inherit from something else and still implement the interface, or if you want to implement the interface but not inherit the base class implementation. An example might help:
// Your interface
interface IFoo { void A(); void B; }
// A "default" implementation of that interface
abstract class FooBase : IFoo
{
public abstract void A();
public void B()
{
Console.WriteLine("B");
}
}
// A class that implements IFoo by reusing FooBase partial implementation
class Foo : FooBase
{
public override void A()
{
Console.WriteLine("A");
}
}
// This is a different class you may want to inherit from
class Bar
{
public void C()
{
Console.WriteLine("C");
}
}
// A class that inherits from Bar and implements IFoo
class FooBar : Bar, IFoo
{
public void A()
{
Console.WriteLine("Foobar.A");
}
public void B()
{
Console.WriteLine("Foobar.B");
}
}
Yes, and if all the classes you need to do this for are logically subclasses of an existing abstract base class, then add an abstract method to the base class... This is better than an interface because it allows you to add implementation later (by changing abstract base class method to virtual method with a default implementation), if/when it turns out that, say, eight of ten derived classes will have the same implementation, and say, only two of them differ...
EDIT: (based on thread in comments below) The base class must be declared as abstract to do this... You can't have an abstract method in a non-abstract class because a non-abstract class can be instantiated, and if an instance of it was created, there wouldbe NO implementation for that method. So this is illegal. By declaring the base as abstract, you inhibit instantiation of the class. Then, only non-abstract derived classes can be instantiated, where, (because the base method is abstract) you MUST add an implementation for that method.
And full worker sample with params (.netcore 2.2):
class User{
public string Name = "Fen";
}
class Message{
public string Text = "Ho";
}
// Interface
interface IWorkerLoop
{
// Working with client message
string MessageWorker(string msg);
}
// AbstractWorkerLoop partial implementation
public abstract class AbstractWorkerLoop : IWorkerLoop
{
public User user;
public Message msg;
// Append session object to loop
public abstract AbstractWorkerLoop(ref User user, ref Message msg){
this.user = user;
this.msg = msg;
}
public abstract string MessageWorker(string msg);
}
// Worker class
public class TestWorkerLoop : AbstractWorkerLoop
{
public TestWorkerLoop(ref User user, ref Message msg) : base(user, msg){
this.user = user;
this.msg = msg;
}
public override string MessageWorker(string msg){
// Do something with client message
return "Works";
}
}