Class inheriting from several Interfaces having same method signature - c#

Say, I have three interfaces:
public interface I1
{
void XYZ();
}
public interface I2
{
void XYZ();
}
public interface I3
{
void XYZ();
}
A class inheriting from these three interfaces:
class ABC: I1,I2, I3
{
// method definitions
}
Questions:
If I implement like this:
class ABC: I1,I2, I3
{
public void XYZ()
{
MessageBox.Show("WOW");
}
}
It compiles well and runs well too!
Does it mean this single method implementation is sufficient for inheriting all the three Interfaces?
How can I implement the method of all the three interfaces and CALL THEM?
Something Like this:
ABC abc = new ABC();
abc.XYZ(); // for I1 ?
abc.XYZ(); // for I2 ?
abc.XYZ(); // for I3 ?
I know it can done using explicit implementation but I'm not able to call them. :(

If you use explicit implementation, then you have to cast the object to the interface whose method you want to call:
class ABC: I1,I2, I3
{
void I1.XYZ() { /* .... */ }
void I2.XYZ() { /* .... */ }
void I3.XYZ() { /* .... */ }
}
ABC abc = new ABC();
((I1) abc).XYZ(); // calls the I1 version
((I2) abc).XYZ(); // calls the I2 version

You can call it. You just have to use a reference with the interface type:
I1 abc = new ABC();
abc.XYZ();
If you have:
ABC abc = new ABC();
you can do:
I1 abcI1 = abc;
abcI1.XYZ();
or:
((I1)abc).XYZ();

During implementation in a class do not specify modifier o/w you will get compilation error, also specify the interface name to avoid ambiguity.You can try the code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleCSharp
{
class Program
{
static void Main(string[] args)
{
MyClass mclass = new MyClass();
IA IAClass = (IA) mclass;
IB IBClass = (IB)mclass;
string test1 = IAClass.Foo();
string test33 = IBClass.Foo();
int inttest = IAClass.Foo2();
string test2 = IBClass.Foo2();
Console.ReadKey();
}
}
public class MyClass : IA, IB
{
static MyClass()
{
Console.WriteLine("Public class having static constructor instantiated.");
}
string IA.Foo()
{
Console.WriteLine("IA interface Foo method implemented.");
return "";
}
string IB.Foo()
{
Console.WriteLine("IB interface Foo method having different implementation. ");
return "";
}
int IA.Foo2()
{
Console.WriteLine("IA-Foo2 which retruns an integer.");
return 0;
}
string IB.Foo2()
{
Console.WriteLine("IA-Foo2 which retruns an string.");
return "";
}
}
public interface IA
{
string Foo(); //same return type
int Foo2(); //different return tupe
}
public interface IB
{
string Foo();
string Foo2();
}
}

Related

Inheritance from multiple interfaces with the same method name to abstract class [duplicate]

If we have a class that inherits from multiple interfaces, and the interfaces have methods with the same name, how can we implement these methods in my class? How can we specify which method of which interface is implemented?
By implementing the interface explicitly, like this:
public interface ITest {
void Test();
}
public interface ITest2 {
void Test();
}
public class Dual : ITest, ITest2
{
void ITest.Test() {
Console.WriteLine("ITest.Test");
}
void ITest2.Test() {
Console.WriteLine("ITest2.Test");
}
}
When using explicit interface implementations, the functions are not public on the class. Therefore in order to access these functions, you have to first cast the object to the interface type, or assign it to a variable declared of the interface type.
var dual = new Dual();
// Call the ITest.Test() function by first assigning to an explicitly typed variable
ITest test = dual;
test.Test();
// Call the ITest2.Test() function by using a type cast.
((ITest2)dual).Test();
You must use explicit interface implementation
You can implement one or both of those interfaces explicitly.
Say that you have these interfaces:
public interface IFoo1
{
void DoStuff();
}
public interface IFoo2
{
void DoStuff();
}
You can implement both like this:
public class Foo : IFoo1, IFoo2
{
void IFoo1.DoStuff() { }
void IFoo2.DoStuff() { }
}
You can implement one interface Explicitly and another implecitely.
public interface ITest {
void Test();
}
public interface ITest2 {
void Test();
}
public class Dual : ITest, ITest2
{
public void Test() {
Console.WriteLine("ITest.Test");
}
void ITest2.Test() {
Console.WriteLine("ITest2.Test");
}
}
ITest.Test will be the default implementation.
Dual dual = new Dual();
dual.Test();
((ITest2)dual).Test();
Output:
Console.WriteLine("ITest.Test");
Console.WriteLine("ITest2.Test");
Sometimes you may even need to do:
public class Foo : IFoo1, IFoo2
{
public void IFoo1.DoStuff() { }
public void IFoo2.DoStuff()
{
((IFoo1)this).DoStuff();
}
}
public class ImplementingClass : AClass1, IClass1, IClass2
{
public override string Method()
{
return "AClass1";
}
string IClass1.Method()
{
return "IClass1";
}
string IClass2.Method()
{
return "IClass2";
}
}
So when calling from different class you will have to type cast the object into required Interface or Abstract class.
ImplementingClass implementingClass = new ImplementingClass();
((AClass1)implementingClass).Method();
public interface IDemo1
{
void Test();
}
public interface IDemo2
{
void Test();
}
public class clsDerived:IDemo1,IDemo2
{
void IDemo1.Test()
{
Console.WriteLine("IDemo1 Test is fine");
}
void IDemo2.Test()
{
Console.WriteLine("IDemo2 Test is fine");
}
}
public void get_methodes()
{
IDemo1 obj1 = new clsDerived();
IDemo2 obj2 = new clsDerived();
obj1.Test();//Methode of 1st Interface
obj2.Test();//Methode of 2st Interface
}
Answer is "By using explicit Interface implementation"
Take one example:
using System;
interface A
{
void Hello();
}
interface B
{
void Hello();
}
class Test : A, B
{
void A.Hello()
{
Console.WriteLine("Hello to all-A");
}
void B.Hello()
{
Console.WriteLine("Hello to all-B");
}
}
public class interfacetest
{
public static void Main()
{
A Obj1 = new Test();
Obj1.Hello();
B Obj2 = new Test();
Obj2.Hello();
}
}
Output:
Hello to all-A
Hello to all-B
Dual dual = new Dual();
(dual as ITest).Test();
(dual as ITest2).Test();
you can use that for your code

Array of inherited from generic types

Code to demonstrate the problem:
static void Main(string[] args)
{
var a = new A();
var b = new B();
Base<>[] all = new Base<>[] { a, b }; // doesn't work
}
class Base<T>
{
public string Caption { get { return typeof(T).ToString(); } }
}
class A : Base<A> { }
class B : Base<B> { }
Perhaps I went the wrong direction. Idea was to move Caption into base class (Base become generic). Non-generic version works without problems:
var all = new Base[] { a, b }; // no problems for as long as Base is not generic
There's no Type<?> in C# - you always have to specify a concrete generic type.
The only way around this is to make Base<T> inherit a non-generic base-class, or implement a non-generic interface. You could then use that as the type of the array.
EDIT:
In your case this is extremely simple, since the part of the interface you want doesn't include the generic type argument. So you can simply do either:
public abstract class Superbase
{
public abstract string Caption { get; }
}
public class Base<T>: Superbase
{
public override string Caption { get { return typeof(T).Name; } }
}
Or, using an interface:
public interface IBase
{
string Caption { get; }
}
public class Base<T>: IBase
{
public string Caption { get { return typeof(T).Name; } }
}
Your array would then be Superbase[] or IBase[], respectivelly. In both cases, you can see that I'm not actually providing an implementation - both the declarations are "abstract", in a sense.
In general, I'm trying to keep the non-generic stuff in a non-generic base class, rather than stuffing it in the derived generic classes. It just feels more clean :)
based on #Luaan ideea, here is an implementation:
class Program
{
static void Main(string[] args)
{
var a = new A();
var b = new B();
var arr = new Base[] { a, b};
foreach (var obj in arr)
Console.WriteLine(obj.Caption);
Console.ReadKey();
}
}
public class Base<T> : Base
{
public override string Caption
{
get { return typeof (T).ToString(); }
}
}
public class A : Base<A> { }
public class B : Base<B> { }
public abstract class Base
{
public abstract string Caption { get; }
}
Instead of trying to use inheritance (which will lead to more problems down the line), use an extension method instead:
public interface IClassAORClassB {}
class A : IClassAORClassB { }
class B : IClassAORClassB { }
public static class Captions
{
public static string Caption<T>(this T obj) where T : IClassAORClassB
{
return obj.GetType().ToString();
}
}
static void Main(string[] args)
{
var a = new A();
var b = new B();
var all = new IClassAORClassB[] { a, b }; // works just fine
Console.WriteLine(all[0].Caption()); // prints A
Console.WriteLine(all[1].Caption()); // prints B
}

Accessing a function in polymorphism

There are 3 classes A,B,C . Classes B and C inherit from A.
Class B and C have a function - func1() ,A doesnt.
I have a list<A> OB where every object in it is eaither B or C.
I want to access func1 by OB[0].Func1().
How can i do this?
Thank you!
You're trying to call method func1 on class A, where A does not define it? You can't. You can make Func1 abstract within A if you want to do that.
abstract class A
{
public abstract Func1();
}
class B : A
{
public override Func1()
{
MessageBox.Show("Hello World");
}
}
class C : A
{
public override Func1()
{
MessageBox.Show("Goodbye World");
}
}
The fact that Func1 is abstract means that you can't instantiate A directly, but you can instantiate B.
var listOfA = new List<A>();
listOfA.Add(new B());
listOfA.Add(new C());
listOfA[0].Func1(); // hello world
listOfA[1].Func1(); // goodbye world
You could make Func1 defined as virtual in A instead of setting it as abstract, but I recommend you do not because this will introduce a reversed Refused Bequest design smell.
Add the method to class A as virtual, and make B and C override it:
public class A
{
public virtual void Foo()
{
}
}
public class B : A
{
public override void Foo()
{
}
}
public class C : A
{
public override void Foo()
{
}
}
If it doesn't make sense put func1() or can't change class A you can create a Interface that has func1() and have just class B and C implement that interface. Then when you need to call func1() cast your objects to that interface using the as operator. When using the as operator no exception is thrown if the cast fails.
public interface MyInterface
{
void func1();
}
public class B : MyInterface
{
public func1() {...}
....
}
public class C : MyInterface
{
public void func1() {...}
....
}
//example of calling func1()
List<A> list = new List<A>(stuff);
foreach(A item in list)
{
MyInterface tmp = item as MyInterface;
if(tmp != null)
{
tmp.func1();
}
}
Abstract factory do the same thing you are looking for
i found this code on CodeProject
this might help you
//Let's define type of bread bases
public enum BreadBase
{
HotIndianMasalaBase,
PunjabiTadkaBase,
ItalianCheeseBase,
VeggieBase,
}
//This is a breadfactory where people visit to get their favorite bread bases
public interface BreadFactory
{
Bread GetBread(BreadBase BreadBase);
}
//The abstract bread
public interface Bread
{
void Bake();
}
//create concrete classes
public class HotIndianMasalaBread :Bread
{
public void Bake()
{
Console.WriteLine ("For you::Hotindian Masala base Bread.");
}
}
public class VeggieBread : Bread
{
public void Bake()
{
Console.WriteLine("For you::Veggie base Bread.");
}
}
public class ItalianCheeseBread : Bread
{
public void Bake()
{
Console.WriteLine("For you::Italian cheese base Bread.");
}
}
public class PunjabiTadkaBaseBread : Bread
{
public void Bake()
{
Console.WriteLine("For you::Punjabi tadka base bread.");
}
}
//Lets create bread factories aka concrete classes
public class AmericanBreadFactory :BreadFactory
{
public Bread GetBread(BreadBase BreadBase)
{
Bread vBread = null;
switch (BreadBase)
{
case BreadBase.VeggieBase:
vBread = new VeggieBread();
break;
case BreadBase.ItalianCheeseBase:
vBread = new ItalianCheeseBread();
break;
}
return vBread;
}
}
public class IndianBreadFactory :BreadFactory
{
public Bread GetBread(BreadBase BreadBase)
{
Bread vBread = null;
switch (BreadBase)
{
case BreadBase.HotIndianMasalaBase:
vBread = new HotIndianMasalaBread();
break;
case BreadBase.PunjabiTadkaBase:
vBread = new PunjabiTadkaBaseBread();
break;
}
return vBread;
}
}
//lets order breads
class Program
{
static void Main(string[] args)
{
//example of abstract factory
AmericanBreadFactory vAmericanBread = new AmericanBreadFactory();
Bread vBread = vAmericanBread.GetBread(BreadBase.VeggieBase);
vBread.Bake();
//lets bak indian punjabi tadka bread
IndianBreadFactory vIndianBreadFactory = new IndianBreadFactory();
Bread vIndianBread = vIndianBreadFactory.GetBread(BreadBase.PunjabiTadkaBase);
vIndianBread.Bake();
}
}

Inheritance same methods implementation

I have the following code. (in c#)
interface 1:
public interface iBclass
{
int addition(int a);
int s(); //and more methods from this ......
}
interface 2:
public interface iAclass
{
int addition(int a);
//more methods.....
}
Class that inherits both interfaces:
public class dClass : iAclass , iBclass
{
int iAclass.addition(int a)
{
return 0;
}
int iBclass.addition(int a)
{
return 1;
}
public int s()
{
return 3;
}
}
the problem is i am not able to access the Method iAclass.addition(int a) and iBclass.addition(int a) with the d object.
dClass d = new dClass();
how can i access those method by 'd' object? and why those interface methods are not allow to define as public?
The interfaces are implemented explicitly. So you can only call them by using the interface:
dClass d = new dClass();
iAclass a = (iAclass)d;
a.addition(123); // Calls implementation for iAclass
iBclass b = (iBclass)d;
b.addition(123); // Calls implementation for iBclass
See this link for details.

Specific types in implementing class when using an interface

Consider the following code sample:
interface IData {
int Count();
}
interface IOperations {
IData Foo();
double Bar(IData a);
}
class Data1 : IData {
public int Count() { return 37; }
public double SomethingElse { get; set; }
}
class Ops1 : IOperations
{
public Data1 Foo() { return new Data1(); } // want to return specific type here
public double Bar(Data1 x) { ... } // want to get specific type here
// and not use operator as everywhere
}
// more definitions of classes Data2, Ops2, Data3, Ops3, ...
// some code:
Ops1 a = new Ops1();
Data1 data = a.Foo(); // want Data1 here not IData!
double x = a.Bar(data);
I could of course just use public IData Foo() { return new Data1(); }:
// some code
Ops1 a = new Ops1();
Data1 data = a.Foo() as Data1;
but with as everywhere, the code is quickly becoming confusing.
I wonder if there is a good design pattern to achieve this in a clear and strong way?
Edit: Is is important, that Ops and Data share a common base class:
List<IOperations> ops = ...;
List<IData> data = ...;
List<double> result = ...;
for(int i=0; i<ops.Count; i++)
result[i] = ops[i].Bar(data[i]);
So for the case with the return type, I wonder that this is forbidden, because I satisfy the requirement of the interface. In the case with parameters probably there is some additional (template) layer required.
You could use generics:
interface IOperations<T> where T: IData
{
T Foo();
double Bar(T a);
}
class Ops1 : IOperations<Data1>
{
public Data1 Foo() { return new Data1(); }
public double Bar(Data1 x) { /* ... */ }
}

Categories