65.9K
CodeProject 正在变化。 阅读更多。
Home

接口的多重继承

starIconstarIconstarIcon
emptyStarIcon
starIcon
emptyStarIcon

3.56/5 (16投票s)

2008年2月14日

CPOL

2分钟阅读

viewsIcon

65568

这篇文章讨论了当两个接口中存在同名函数,并且一个派生类调用它时发生的情况。

引言

这篇文章介绍了被称为接口冲突的情况。当两个接口具有相同名称和签名的函数,并且一个基类实现了这些接口时,就会发生这种情况。

背景

在早期的语言(如 C++)中,存在多重继承的概念。但在 C# 中,我们没有任何此类特性。这是 C++ 中存在但 C# 中没有的特性之一。由于 C++ 中的这个特性,开发人员面临着菱形继承的问题。这就是虚拟函数出现的原因。

Using the Code

在 C# 中,当两个接口具有相同名称的函数,并且一个类实现了这些接口时,我们必须专门处理这种情况。我们必须告诉编译器我们要实现哪个类的函数。对于这种情况,我们必须在函数实现期间使用接口的名称。看下面的例子

代码块应设置为样式 Formatted,如下所示

Ex:
    /// 
    /// Interface 1
    /// 
    public interface Interface1
    {
        /// 
        /// Function with the same name as Interface 2
        /// 
        void MyInterfaceFunction();
    }

    /// 
    /// Interface 2
    /// 
    public interface Interface2
    {
        /// 
        /// Function with the same name as Interface 1
        /// 
        void MyInterfaceFunction();
    }

    /// 
    /// MyTestBaseClass Implements the two interfaces Interface1 and Interface2
    /// 
    public class MyTestBaseClass:Interface1,Interface2
    {
        #region Interface1 Members

        void Interface1.MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyInterface1 Function()");
            return;
        }

        #endregion

        #region Interface2 Members

        void Interface2.MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyInterface2 Function()");
            return;
        }

        #endregion
    }

在上面的例子中,我们使用它的接口名称来实现函数 MyInterfaceFunction()。在这种情况下,如果我们创建 MyTestBaseClass 的对象并检查 MyInterfaceFunction(),它将无法直接使用。查看以下代码

MyTestBaseClass obj = new MyTestBaseClass();
//Following code would give an error saying that
//class does not have a definition for MyInterfaceFunction.
obj.MyInterfaceFunction();

我们可以通过将其强制转换为相应的接口来调用相应的接口函数。请看下面的例子

//This code would work fine and calls the function of the first interface
((Interface1)obj).MyInterfaceFunction();

//This code would also work fine and calls the function of the second interface
((Interface2)obj).MyInterfaceFunction();

现在出现转折。我们将在 MyTestBaseClass 中添加一个同名的函数。现在尝试访问 MyTestBaseClass 对象的元素。您将看到 MyInterfaceFunction 在那里可用。现在看下面的代码,这段代码将首先调用接口的函数,然后调用 Class 函数。

Ex.
    /// 
    /// MyTestBaseClass implements the two interfaces Interface1 and Interface2
    /// 
    public class MyTestBaseClass:Interface1,Interface2
    {
        public void MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyTestBaseClass's Function()");
            return;
        }

        #region Interface1 Members

        void Interface1.MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyInterface1 Function()");
            return;
        }

        #endregion

        #region Interface2 Members

        void Interface2.MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyInterface2 Function()");
            return;
        }

        #endregion
    }

    /// 
    /// Interface 1
    /// 
    public interface Interface1
    {
        /// 
        /// Function with Same Name as Interface 2
        /// 
        void MyInterfaceFunction();
    }

    /// 
    /// Interface 2
    /// 
    public interface Interface2
    {
        /// 
        /// Function with Same Name as Interface 1
        /// 
        void MyInterfaceFunction();
    }

In the Main Function – 

MyTestBaseClass obj = new MyTestBaseClass();

//This code would work fine and calls the function of the first interface
((Interface1)obj).MyInterfaceFunction();

//This code would work fine and calls the function of the second interface
((Interface2)obj).MyInterfaceFunction();

//This code would call the class function
obj.MyInterfaceFunction();

现在又出现一个转折。你从 MyTestBaseClass() 派生一个类 MyDerivedClass()。在此之前,删除最后在 MyTestBaseClass() 中实现的函数。现在创建 MyDerivedClass() 的实例并检查。即使它的基类具有这些函数,该类也将没有任何函数可用。

Ex:
    /// 
    /// Interface 1
    /// 
    public interface Interface1
    {
        /// 
        /// Function with the same name as Interface 2
        /// 
        void MyInterfaceFunction();
    }

    /// 
    /// Interface 2
    /// 
    public interface Interface2
    {
        /// 
        /// Function with the same name as Interface 1
        /// 
        void MyInterfaceFunction();
    }

    /// 
    /// MyTestBaseClass implements the two interfaces Interface1 and Interface2
    /// 
    public class MyTestBaseClass:Interface1,Interface2
    {

        //public void MyInterfaceFunction()
        //{
        //    MessageBox.Show("Frm MyTestBaseClass's Function()");
        //    return;
        //}

        #region Interface1 Members

        void Interface1.MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyInterface1 Function()");
            return;
        }

        #endregion

        #region Interface2 Members

        void Interface2.MyInterfaceFunction()
        {
            MessageBox.Show("Frm MyInterface2 Function()");
            return;
        }

        #endregion
    }

    /// 
    /// New Derived class which is derived from MyTestBaseClass
    /// 
    public class MyDerivedClass : MyTestBaseClass
    {
        //No Functions Here....
    }

因此,在这里再次为了获取接口的函数,我们必须将派生类的对象与接口分开进行类型转换。请看下面的代码

//In the Main Function……

//This code would call the Interface1 function
MyDerivedClass derivedObj = new MyDerivedClass();
((Interface1)derivedObj).MyInterfaceFunction();        

结论

从上面的文章中,您应该了解在发生冲突时调用接口函数的方法。欢迎您的建议和意见。

© . All rights reserved.