代码之家  ›  专栏  ›  技术社区  ›  jfs

C接口的非公共成员[关闭]

  •  28
  • jfs  · 技术社区  · 16 年前

    在C中,当您实现一个接口时,所有成员都是隐式公共的。如果我们能指定可访问性修饰符不是更好吗( protected , internal ,除了 private 当然),还是应该使用抽象类?

    9 回复  |  直到 6 年前
        1
  •  36
  •   shA.t Rami Jamleh    7 年前

    如果接口是内部的,那么它的所有成员都是程序集的内部成员。如果嵌套接口受到保护,则只有外部类的子类才能访问该接口。

    接口在其声明程序集之外的内部成员将是毫无意义的,正如在其声明的外部类之外的接口的受保护成员一样。

    合同 在实现类型和接口用户之间。外面的人不会也不应该在意 关心实现,这就是内部成员和受保护成员的作用。

    全部的 成员是抽象的)在这种情况下,受保护的成员是无用的。在这种情况下,使用一个接口并保存一个基类来实现要选择的类型。

        2
  •  21
  •   Manoj Sharma    7 年前

    public interface IInterface {
        public void Method();
    }
    
    public class A : IInterface {
        public void IInterface.Method() {
            // Do something
        }
    }
    
    public class Program {
        public static void Main() {
            A o = new A();
            o.Method(); // Will not compile
            ((IInterface)o).Method(); // Will compile
        }
    }
    
        3
  •  5
  •   Ishmaeel    16 年前

    不会有道理的。接口是与 支持这些方法和属性。坚持抽象类。

        4
  •  3
  •   Community Egal    7 年前

    接口就是这样的,它们是通用的公共规范。

    这是讨论最多的帖子,当这个问题浮现在我脑海中时,让我贴出两个我在上面找到的极好的答案。

    This answer gives an example 对于派生类中的接口成员使用非统一的访问说明符是多么的无意义。代码总是比技术描述好。

    Jon Skeet explains here that's by design sadly .

        5
  •  2
  •   Community Egal    7 年前

    实现所有类的接口都是一个契约。这意味着他们必须全部遵守,或者不遵守。

    如果接口是公共的,那么联系人的每一部分都必须是公共的,否则对朋友/内部类意味着一个,而对其他所有的都是不同的。

    或者使用一个抽象基类或者(如果可能并且可行的话)一个 internal extension method on the interface .

        6
  •  2
  •   Rook    7 年前

    您可以隐藏由外部程序集的接口实现的几乎所有代码。

    interface IVehicle
    {
        void Drive();
        void Steer();
        void UseHook();
    }
    abstract class Vehicle  // :IVehicle  // Try it and see!
    {
        /// <summary>
        /// Consuming classes are not required to implement this method.
        /// </summary>
        protected virtual void Hook()
        {
            return;
        }
    }
    class Car : Vehicle, IVehicle
    {
        protected override void Hook()  // you must use keyword "override"
        {
            Console.WriteLine(" Car.Hook(): Uses abstracted method.");
        }
        #region IVehicle Members
    
        public void Drive()
        {
            Console.WriteLine(" Car.Drive(): Uses a tires and a motor.");
        }
    
        public void Steer()
        {
            Console.WriteLine(" Car.Steer(): Uses a steering wheel.");
        }
        /// <summary>
        /// This code is duplicated in implementing classes.  Hmm.
        /// </summary>
        void IVehicle.UseHook()
        {
            this.Hook();
        }
    
        #endregion
    }
    class Airplane : Vehicle, IVehicle
    {
        protected override void Hook()  // you must use keyword "override"
        {
            Console.WriteLine(" Airplane.Hook(): Uses abstracted method.");
        }
        #region IVehicle Members
    
        public void Drive()
        {
            Console.WriteLine(" Airplane.Drive(): Uses wings and a motor.");
        }
    
        public void Steer()
        {
            Console.WriteLine(" Airplane.Steer(): Uses a control stick.");
        }
        /// <summary>
        /// This code is duplicated in implementing classes.  Hmm.
        /// </summary>
        void IVehicle.UseHook()
        {
            this.Hook();
        }
    
        #endregion
    }
    

    class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car();
            IVehicle contract = (IVehicle)car;
            UseContract(contract);  // This line is identical...
            Airplane airplane = new Airplane();
            contract = (IVehicle)airplane;
            UseContract(contract);  // ...to the line above!
        }
    
        private static void UseContract(IVehicle contract)
        {
            // Try typing these 3 lines yourself, watch IDE behavior.
            contract.Drive();
            contract.Steer();
            contract.UseHook();
            Console.WriteLine("Press any key to continue...");
            Console.ReadLine();
        }
    }
    
        7
  •  1
  •   Jon Limjap    16 年前

    接口在它们的方法中没有访问修饰符,让它们对任何合适的访问修饰符开放。这有一个目的:它允许其他类型推断接口后面的对象有哪些方法和属性。给它们提供受保护的/内部的访问器会破坏接口的用途。

    如果您坚信需要为方法提供访问修饰符,可以将其排除在接口之外,或者如您所说,使用抽象类。

        8
  •  0
  •   John Topley Damien MATHIEU    16 年前

    我熟悉Java而不是C,但是为什么地球会想要一个接口中的私有成员呢?它不可能有任何实现,并且对于实现类来说是不可见的,因此将是无用的。接口用于指定行为。如果你需要默认行为,那就使用抽象类。

        9
  •  0
  •   Ini    7 年前