为啥我们不能在实现两个接口由相同方法组成的类的方法中使用访问修饰符?

Posted

技术标签:

【中文标题】为啥我们不能在实现两个接口由相同方法组成的类的方法中使用访问修饰符?【英文标题】:Why we can't use access modifier in the methods of class which implements two interfaces consist of same methods?为什么我们不能在实现两个接口由相同方法组成的类的方法中使用访问修饰符? 【发布时间】:2022-01-14 00:03:16 【问题描述】:
public interface A

     void FirstDemo();
     void SecondDemo();

public interface B

     void FirstDemo();
     void SecondDemo();


 public class Demo : A, B
        
            void A.FirstDemo()
            
                Console.WriteLine("This is a function of first method of interface A");
            
            void A.SecondDemo()
            
                Console.WriteLine("This is a function of second method of interface A");
            

            void B.FirstDemo()
            
                Console.WriteLine("This is a function of first method of interface B");
            
            void B.SecondDemo()
            
                Console.WriteLine("This is a function of second method of interface B");
            
        

static void Main(string[] args)
        
            A obj = new Demo();
            obj.SecondDemo();
            B obj1 = new Demo();
            obj1.FirstDemo();
        

这个程序可以正常运行。 但我的困惑是,如果我在 Demo 类中只实现一个接口,那么我可以在该接口的每个方法中给出一个访问修饰符。但是当我尝试实现两个接口 (在这种情况下:A 和 B) 包含相同的方法,在同一个类 (在这种情况下:Demo 类) 然后我' 不允许放置公共访问修饰符。为什么会这样?

注意: 如果我使用单个接口并在 Demo 类中实现它,那么我可以对接口中声明的所有方法使用访问修饰符。那么使用相同方法的多个接口有什么问题呢?

【问题讨论】:

那些是显式的接口实现。它们是隐式公开的 这能回答你的问题吗? Why in C# does one need to mention the access modifier for implementation of an interface property? 是的,我已经浏览了这个链接。但我的困惑是,如果我在 Demo 类中只实现一个接口,那么我可以在该接口的每个方法中给出一个访问修饰符。但是,当我尝试在同一个类(在本例中:Demo 类)中实现包含相同方法的两个接口(在本例中:A 和 B)时,我不允许放置公共访问修饰符。为什么会这样? public void MethodFromInterface()void IFace.MethodFromInterface() 不同:new Obj().MethodFromInterface() 在第一种情况下有效,但在后一种情况下无效。使用显式接口实现,您需要调用((IFace)new Obj()).MethodFromInterface()。您不是在比较 1 与 2 接口,而是在比较 implicitexplicit 接口实现——您在这里混合了两个不同的概念。您的课程甚至使这一点显而易见,但您的调用 main 函数却没有:((A)new Obj()).FirstDemo() 是与 ((B)new Obj()).FirstDemo() 不同的方法。 @knittl 我认为我应该深入研究这个概念。但是谢谢你引起我的注意...... 【参考方案1】:

区别不在于“1 个接口与 2 个接口”,而在于“隐式与显式接口实现”。关于问题的“为什么禁止可见性修饰符”部分的解释,我将参考问题Why in C# does one need to mention the access modifier for implementation of an interface property?。

显式接口实现是隐式公开的。是的,你没看错。)

C# 允许您隐式和显式地实现单个接口,它们成为不同的方法。对象的static类型决定调用哪个方法:

interface IFace 
  void Method();
  void OnlyImplicit();
  void OnlyExplicit();


public class Obj : IFace 
  public void Method() 
    Console.WriteLine("implicit implementation");
  

  void IFace.Method() 
    Console.WriteLine("explicit implementation");
  

  public void OnlyImplicit() 
    Console.WriteLine("only implemented implicitly");
  

  void IFace.OnlyExplicit() 
    Console.WriteLine("only implemented explicitly");
  

  public void Main() 
    Obj o = new Obj(); // or: var o = new Obj();
    IFace i = o;

    o.Method(); // call of implicit impl
    i.Method(); // call of explicit impl

    o.OnlyImplicit(); // call of implicit impl
    i.OnlyImplicit(); // call of implicit impl

    i.OnlyExplicit(); // call of explicit impl

    // compile error, method is implemented explicitly,
    // can only be called when static type is interface;
    // cannot be called when static type is the class' type
    // (this is not so obvious):
    o.OnlyExplicit();
  

【讨论】:

非常感谢......这对我来说真的很有帮助......最后一个问题,你为什么写'void IFace.Method()'而不是'public void IFace.Method()' ? @PrinceGajjar void IFace.Method() 不允许可见性修饰符,这就是 C# 语法的定义方式。有关详细信息,请阅读答案顶部的链接问题 好的...知道了...我对此一无所知...非常感谢您消除了我的困惑...这很明显。【参考方案2】:

为了使用一个对象,你需要一个接口:-)。

您可以隐式实现 una 接口,而另一个显式实现。

你不能为同一个接口方法提供多个不同的实现。否则编译器将如何选择使用的实现?

假设你隐式实现 A 和显式 B:

var demo = new Demo();
demo.FirstDemo(); // it uses public implementation (Demo class interface) that is A
var demoB = (B)demo;
demoB.FirstDemo(); // it uses B interface

【讨论】:

以上是关于为啥我们不能在实现两个接口由相同方法组成的类的方法中使用访问修饰符?的主要内容,如果未能解决你的问题,请参考以下文章

█■为啥要用实现接口的类实例化接口呢? ?

为啥要实现Runnable接口,来实现多线程?把Thread作为父类则不能呢?

接口 (以及与抽象类的区别)

动态实例化实现接口并调用接口方法的类

JAVA知识点总结篇

201671010112 第六周