C#基础-第13章:接口

    * 说明:第2部分:第13章:接口(259)
    * 13.1 本章内容:
        · 类和接口继承
        · 定义接口
        · 继承接口
        · 关于调用接口方法的更多讨论
        · 隐式和显示接口方法的实现
        · 泛型接口
        · 实现多个具有相同方法和签名的接口
        · 用显式接口方法实现来增强编译时类型安全性
        · 谨慎使用显示接口方法实现
        · 设计:基类还是接口?

/* ==============================================================================
  
 ==============================================================================
 */

#define EIMITypeSafety_Version3
#define EIMINoBaseCall_Version2
#if !DEBUG
#pragma warning disable 219
#endif

using System;

public static class Interfaces
{
    public static void Main()
    {
        ImplementingAnInterface.Go();
        InterfaceReimplementation.Go();
        ExplicitInterfaceMethodImpl.Go();
        GenericsAndInterfaces.Go();
        UsingEIMI.Go();
        EIMITypeSafety.Go();
        EIMINoBaseCall.Go();
    }
}

////////////////  继承接口 Demo ////////////////////////////////////

internal static class ImplementingAnInterface //P261
{
    public static void Go()
    {
        Point[] points = new Point[] {
         new Point(3, 3),
         new Point(1, 2),
      };

        if (points[0].CompareTo(points[1]) > 0)
        {
            Point tempPoint = points[0];
            points[0] = points[1];
            points[1] = tempPoint;
        }
        Console.WriteLine("Points from closest to (0, 0) to farthest:");
        foreach (Point p in points)
            Console.WriteLine(p);
    }

    // Point 从System.Object派生,并实现了IComparable<T>
    public sealed class Point : IComparable<Point>
    {
        private Int32 m_x, m_y;

        public Point(Int32 x, Int32 y)
        {
            m_x = x;
            m_y = y;
        }

        // 该方法为Point实现 IComparable<T>.CompareTo()
        public Int32 CompareTo(Point other)
        {
            return Math.Sign(Math.Sqrt(m_x * m_x + m_y * m_y)
               - Math.Sqrt(other.m_x * other.m_x + other.m_y * other.m_y));
        }

        public override String ToString()
        {
            return String.Format("({0}, {1})", m_x, m_y);
        }
    }
}

/// <summary>
/// 派生类不能重写sealed的接口方法的另外实现。见P262
/// </summary>
internal static class InterfaceReimplementation//
{
    public static void Go()
    {
        /************************* 第一个例子 *************************/
        Base b = new Base();

        // 用b的类型来调用Dispose,显示 "Base's Dispose"
        b.Dispose();

        // 用b的对象的类型来调用 Dispose
        ((IDisposable)b).Dispose();


        /************************* 第二个例子 ************************/
        Derived d = new Derived();

        // 用d的类型来调用Dispose显示 "Derived's Dispose"
        d.Dispose();

        // 用d的对象的类型调用Dispose,显示: "Derived's Dispose"
        ((IDisposable)d).Dispose();


        /************************* 第三个例子 *************************/
        b = new Derived();

        // 用b的类型来调用Dispose显示: "Base's Dispose"
        b.Dispose();

        // 用b的对象的类型调用Dispose,显示: "Derived's Dispose"
        ((IDisposable)b).Dispose();
    }

    // 这个类派生自Object,它实现了IDispoable
    internal class Base : IDisposable
    {
        // 这个方法隐式密封,不能被重写
        public void Dispose()
        {
            Console.WriteLine("Base's Dispose");
        }
    }

    // 这个类派生自Base,它重新实现了IDispoable
    internal class Derived : Base, IDisposable
    {
        //这个方法不能重写Base的Dispose
        //'new'表明该方法重新实现了IDisposable的Dispose方法
        new public void Dispose()
        {
            Console.WriteLine("Derived's Dispose");

            // 注意: 下面这个行代码展示了如何调用基类的实现(如果需要的话)
            // base.Dispose();
        }
    }
}

/// <summary>
/// 隐式和显式接口方法的实现 P264
/// </summary>
internal static class ExplicitInterfaceMethodImpl
{
    public static void Go()
    {
        SimpleType st = new SimpleType();

        // 调用公共Dispose方法实现
        st.Dispose();

        // 调用 IDisposable 的 Dispose 方法的实现
        IDisposable d = st;
        d.Dispose();
    }

    public sealed class SimpleType : IDisposable //265
    {
#if false
    public void Dispose() { Console.WriteLine("Dispose"); }
#else
        public void Dispose() { Console.WriteLine("public Dispose"); }
        void IDisposable.Dispose() { Console.WriteLine("IDisposable Dispose"); }
#endif
    }
}

/// <summary>
/// 泛型接口 P266
/// </summary>
internal static class GenericsAndInterfaces
{
    public static void Go()
    {
        Number n = new Number();

        // Here, I compare the value in n with an Int32 (5)
        IComparable<Int32> cInt32 = n;
        Int32 result = cInt32.CompareTo(5);

        // Here, I compare the value in n with a String ("5")
        IComparable<String> cString = n;
        result = cString.CompareTo("5");
    }

    // 该类实现泛型IComparable<T>接口两次
    public sealed class Number : IComparable<Int32>, IComparable<String>
    {
        private Int32 m_val = 5;

        // 该方法实现 IComparable<Int32> 的CompareTo
        public Int32 CompareTo(Int32 n)
        {
            return m_val.CompareTo(n);
        }

        // 该方法实现 IComparable<String>的CompareTo
        public Int32 CompareTo(String s)
        {
            return m_val.CompareTo(Int32.Parse(s));
        }
    }

    private static void SomeMethod1()
    {
        Int32 x = 1, y = 2;
        IComparable c = x;

        // CompareTo 期待 Object; 传递一个 y (一个 Int32)没有问题
        
        c.CompareTo(y);     // y在这里装箱

        // CompareTo 期待Object; 传递 "2" (一个 String) 可以编译
        // 但是运行时抛出ArgumentException异常
        c.CompareTo("2");
    }

    private static void SomeMethod2()
    {
        Int32 x = 1, y = 2;
        IComparable<Int32> c = x;

        // CompareTo 期待 Object; 传递一个 y (一个 Int32)没有问题
        c.CompareTo(y);     // y在这里不装箱

        // CompareTo 期待Object; 传递 "2" (一个 String) 可以编译
        // 指出String不能为转为Int32
        // c.CompareTo("2");
    }

    /// <summary>
    /// 泛型和接口的约束
    /// </summary>
    public sealed class SomeType
    {
        private static void Test()
        {
            Int32 x = 5;

            // 对M的调用能通过编译,因为Int32实现了IComparable AND IConvertible
            M(x);

            // 这个M调用导致编译错误,因为GUID虽然实现了IComparable
            // 但是没有实现IConvertibles
            Guid g = new Guid();
            // M(g); //这里会报错
        }

        private static Int32 M<T>(T t) where T : IComparable, IConvertible
        {
            // ...
            return 0;
        }
    }
}

/// <summary>
/// 实现多个具有相同方法名和签名的接口
/// </summary>
internal static class UsingEIMI
{
    public static void Go()
    {
        MarioPizzeria mp = new MarioPizzeria();

        // 这里调用的MarioPizzeria的公共方法
        mp.GetMenu();

        // 下面代码调用的 MarioPizzeria的IWindow.GetMenu 方法
        IWindow window = mp;
        window.GetMenu();

        // 下面代码调用的 MarioPizzeria的 IRestaurant.GetMenu 方法
        IRestaurant restaurant = mp;
        restaurant.GetMenu();
    }

    public interface IWindow
    {
        Object GetMenu();
    }

    public interface IRestaurant
    {
        Object GetMenu();
    }

    // 这个类型派生自 System.Object 并 
    // 实现了  IWindow 和 IRestaurant 接口.
    public class MarioPizzeria : IWindow, IRestaurant
    {

        // 这个是IWindows 的 GetMenu() 实现
        Object IWindow.GetMenu()
        {
            // ...
            return null;
        }

        // 这个是 IRestaurant’s GetMenu 方法的实现.
        Object IRestaurant.GetMenu()
        {
            // ...
            return null;
        }

        // 这个是GetMenu方法是可以选的,与接口无关
        // to do with an interface.
        public Object GetMenu()
        {
            // ...
            return null;
        }
    }
}

public static class EIMITypeSafety
{
    internal struct SomeValueType : IComparable
    {
        private Int32 m_x;
        public SomeValueType(Int32 x) { m_x = x; }

#if EIMITypeSafety_Version1
   public Int32 CompareTo(Object other) {
      return (m_x - ((SomeValueType)other).m_x);
   }
#else
        public Int32 CompareTo(SomeValueType other)
        {
            return (m_x - other.m_x);
        }

        // NOTE: No public/private used on the next line
        Int32 IComparable.CompareTo(Object other)
        {
            return CompareTo((SomeValueType)other);
        }
#endif
    }

    public static void Go()
    {
#if EIMITypeSafety_Version1
      SomeValueType v = new SomeValueType(0);
      Object o = new Object();
      Int32 n = v.CompareTo(v);  // Undesired boxing
      n = v.CompareTo(o);        // InvalidCastException
#endif

#if EIMITypeSafety_Version2
      SomeValueType v = new SomeValueType(0);
      Object o = new Object();
      Int32  n = v.CompareTo(v); // No boxing
      n = v.CompareTo(o);        // compile-time error 
#endif

#if EIMITypeSafety_Version3
        SomeValueType v = new SomeValueType(0);
        IComparable c = v;          // Boxing!

        Object o = new Object();
        Int32 n = c.CompareTo(v);         // Undesired boxing
        n = c.CompareTo(o);   // InvalidCastException
#endif
    }
}

internal static class EIMINoBaseCall
{
#if EIMINoBaseCall_Version1
internal class Base : IComparable {
   // Explicit Interface Method Implementation
   Int32 IComparable.CompareTo(Object o) {
      Console.WriteLine("Base's CompareTo");
      return 0;
   }
}

internal class Derived : Base, IComparable {
   // A public method that is also the interface implementation
   public Int32 CompareTo(Object o) {
      Console.WriteLine("Derived's CompareTo");

      // This attempt to call the base class's EIMI causes a compiler error:
      // error CS0117: 'Base' does not contain a definition for 'CompareTo'
      base.CompareTo(o);
      return 0;
   }
}
#endif

#if EIMINoBaseCall_Version2
    internal class Base : IComparable
    {

        // Explicit Interface Method Implementation
        Int32 IComparable.CompareTo(Object o)
        {
            Console.WriteLine("Base's IComparable CompareTo");
            return CompareTo(o);   // This now calls the virtual method
        }

        // Virtual method for derived classes (this method could have any name)
        public virtual Int32 CompareTo(Object o)
        {
            Console.WriteLine("Base's virtual CompareTo");
            return 0;
        }
    }

    internal class Derived : Base, IComparable
    {

        // A public method that is also the interface implementation
        public override Int32 CompareTo(Object o)
        {
            Console.WriteLine("Derived's CompareTo");

            // Now, we can call Base's virtual method
            base.CompareTo(o);
            return 0;
        }
    }
#endif

    public static void Go()
    {
        Derived d = new Derived();
        d.CompareTo(null);
    }
}

 

posted @ 2019-01-24 09:46  eric.yuan  阅读(222)  评论(0编辑  收藏  举报