[8] Essential C # class - from the design point of view to cognition (polymorphism)

In fact, he said Benpian polymorphic or some far-fetched, because the inherited class also exist polymorphic, for example, we rewrite mechanism, it is contemplated that such a scenario: flight this action, the bird can fly, the aircraft can fly, and in fact, aircraft and birds no parent-child relationship, they are co-owners of behavior: flight . So this blog highlights this point: how to deal with consistent behavior (horizontal relationship) and not the same strain relations (vertical relationship) through an interface . Benpian structure is as follows:
Here Insert Picture Description

Interface definition

Why have an interface? After the introduction of classes and abstract classes (I feel that abstract classes and interfaces belong to the class of intermediate products, both the ability to inherit the base class, but also has the ability to extend the abstract member method) After that, we know, can be achieved by rewriting and abstract members to expand and organize their content. So what's the interface necessary to do? , Since there are classes, interfaces that have to do what? :

  • Interface does not contain any implementation, it can be completely isolated from the implementation details and the services provided
  • In addition to allowing members to share a base class signature, can also share achieved (which is achieved by using a derived class inherits the base class method directly), the interface only allows the sharing of member signatures, can not be shared to achieve (the interface should not provide implementations) .
  • C # is a single inheritance, it can be extended by using the method you want to implement the interface, and the interface is multiple inheritance (implementation) .

The interface is defined as follows,

  interface IFileCompression
    {
        void Compress(string targetFileName, string[] fileList);
        void Uncompress(string compressedFileName, string expandDirectoryName);
    }

Note the following:

  • Interfaces implemented and does not contain any data, it contains only attributes (attribute nor the corresponding support field, attributes can not be used automatically) and instance methods , and does not contain any static member!
  • C # does not allow access modifiers interface, common to all members automatically .
  • When the derived class implements the interface, but also, the base class and comma separated by a colon, it is noted that the base class first, the interface in any order.
  • All members of an interface must implement.
  • Interface never be instantiated, and not an abstract class interfaces, constructors, and even no terminators.
  • The interface must expose converted into one of its type to achieve, but because it's derived classes always achieve its full method, it can be implicitly converted .
  • Do not modify the interface has been released, but version control is achieved by adding a sub-interface to the interface

How abstract class interfaces thrown pot it? An abstract class can not be achieved by way of an interface method but to a derived class implementation.

public interface Ifoo
{
    void Bar();
}

public abstract class Foo : Ifoo
{
    public abstract void Bar();
}

public class Child : Foo
{
    public override void Bar()
    {
        throw new NotImplementedException();
    }
}

Polymorphic interface

How to use the interface to achieve polymorphism, in fact, and implicit transformation similar to oh.

1, the definition of abstract classes and interfaces

  public interface IListable
    {
        // Return the value of each column in the row
        string[] ColumnValues
        {
            get;
        }
    }

    public abstract class PdaItem
    {
        public PdaItem(string name)
        {
            Name = name;
        }

        public virtual string Name { get; set; }
    }

2, define two different implementation class

 public class Contact : PdaItem, IListable
    {
        public Contact(string firstName, string lastName,
            string address, string phone)
            : base(null)
        {
            FirstName = firstName;
            LastName = lastName;
            Address = address;
            Phone = phone;
        }

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public string Address { get; set; }
        public string Phone { get; set; }

        public string[] ColumnValues
        {
            get
            {
                return new string[]
                {
                    FirstName,
                    LastName,
                    Phone,
                    Address
                };
            }
        }

        public static string[] Headers
        {
            get
            {
                return new string[] {
                    "First Name", "Last Name    ", 
                    "Phone       ",
                    "Address                       " };
            }
        }

        // ...
    }

    public class Publication : IListable
    {
        public Publication(string title, string author, int year)
        {
            Title = title;
            Author = author;
            Year = year;
        }

        public string Title { get; set; }
        public string Author { get; set; }
        public int Year { get; set; }

        public string[] ColumnValues
        {
            get
            {
                return new string[]
                {
                    Title,
                    Author,
                    Year.ToString()
                };
            }
        }

        public static string[] Headers
        {
            get
            {
                return new string[] {
                    "Title                                                    ", 
                    "Author             ", 
                    "Year" };
            }
        }

        // ...
    }

3, the definition of the caller interface class and calling methods

 public class ConsoleListControl
    {
        public static void List(string[] headers, IListable[] items)
        {
            int[] columnWidths = DisplayHeaders(headers);

            for(int count = 0; count < items.Length; count++)
            {
                string[] values = items[count].ColumnValues;
                DisplayItemRow(columnWidths, values);
            }
        }
     }

4, defining the entry, implemented method

 public static void Main()
        {
            Contact[] contacts = new Contact[]
            {
              new Contact(
                  "Dick", "Traci",
                  "123 Main St., Spokane, WA  99037",
                  "123-123-1234"),
              new Contact(
                  "Andrew", "Littman",
                  "1417 Palmary St., Dallas, TX 55555",
                  "555-123-4567"),
              new Contact(
                  "Mary", "Hartfelt",
                  "1520 Thunder Way, Elizabethton, PA 44444",
                  "444-123-4567"),
              new Contact(
                  "John", "Lindherst",
                  "1 Aerial Way Dr., Monteray, NH 88888",
                  "222-987-6543"),
              new Contact(
                  "Pat", "Wilson",
                  "565 Irving Dr., Parksdale, FL 22222",
                  "123-456-7890"),
              new Contact(
                  "Jane", "Doe",
                  "123 Main St., Aurora, IL 66666",
                  "333-345-6789")
            };

            // Classes are cast implicitly to
            // their supported interfaces
            ConsoleListControl.List(Contact.Headers, contacts);

            Console.WriteLine();

            Publication[] publications = new Publication[3] {
                new Publication(
                    "The End of Poverty: Economic Possibilities for Our Time",
                    "Jeffrey Sachs", 2006),
                new Publication("Orthodoxy", 
                    "G.K. Chesterton", 1908),
                new Publication(
                    "The Hitchhiker's Guide to the Galaxy",
                    "Douglas Adams", 1979)
                };
            ConsoleListControl.List(
                Publication.Headers, publications);
        }

Implicit call interface methods, each derived class will be used to interface to their implementation:

Contact will achieve the following: The following four output attributes: FirstName, LastName, Phone, Address

Here Insert Picture Description
Publication will achieve the following: Output: Title, Author, Year
Here Insert Picture Description

Interface

Divided into explicit and implicit, interface inheritance and multiple interface inheritance.

Explicit and implicit

In fact, the interface is divided into two implementations, explicit and implicit, to realize described above are implicit, feels like the scene most of the time we use, but sometimes also use explicit implementation:

  public class Program
    {
        public static void Main()
        {
            string[] values;
            Contact contact1, contact2 = null;

            // ...

            // ERROR:  Unable to call ColumnValues() directly
            //         on a contact
            // values = contact1.ColumnValues;

            // First cast to IListable
            values = ((IListable)contact2).ColumnValues;// 显式
            var result = contact1.CompareTo(contact2);// 隐式
        
        }
    }

    public class Contact : PdaItem, IListable, IComparable
    {
        // ...
        public Contact(string name)
            : base(name)
        {
        }

        #region IComparable Members

        public int CompareTo(object obj)  //隐式实现
        { 
            //...
        }
        #endregion

        #region IListable Members
        string[] IListable.ColumnValues    //显式实现
        {
            get
            {
                return new string[] 
          {
              FirstName,
              LastName,
              Phone,
              Address
          };
            }
        }
        #endregion

        protected string LastName { get; set; }
        protected string FirstName { get; set; }
        protected string Phone { get; set; }
        protected string Address { get; set; }
    }

Explicit implementation : values = ((IListable)contact2).ColumnValues;Explicit implementation of interface itself only through calling! You can not use virtual, override or to modify the public!
Implicit realization : var result = contact1.CompareTo(contact2);implicit implementation allows the class to call their own! virtual, override or public are optional parameters.

For the interface members implicitly and explicitly implemented, the key difference lies not in the syntax member declaration, but rather the ability instance, rather than by type of access to members of the interface. Establishment need to model the real world when the class hierarchy "belongs" (is a) the relationship - for example, giraffes "belong" to mammals. These are the "semantic" (semantic) relationship. And the interface used to model the relationship "mechanism" (mechanism) . PdaItem "not" an "comparable" (Comparable) things, but it still implement IComparable. The interface and semantic model-independent, but the details of the mechanism of implementation. Explicit interface to achieve the purpose is to "mechanisms" and "model problems" apart . Requires the caller to first convert the object to the interface (such as IComparable), then the object can be considered "comparable", thereby explicitly distinguish do you want to communicate and model, and want to achieve when handling mechanism .

In general, the best practice is to limit the public level of a class into a "full model" as little as possible, to independent mechanism

  • Members are not a core function of the class , and if so, implicit, such as a method to achieve their own members, if not, use explicit.
  • Interface member name as the class member name is appropriate ? Assuming the Dump ITrace interface () member of the class of the data written to the trace log. In Person or Truck (truck) class implicitly implement Dump () method will confuse the role of . Therefore, the better option is implemented explicitly, can only be called to ensure that the Dump (ITrace by data type), so that it does not cause ambiguity. In short, if the use of members is not clear in the implementation class, on account of explicit implementation.
  • ** if class members have the same signature? ** explicit interface member implementation does not add an element named in the type of declaration space. So, if the type members may conflict already exists, then an explicit interface with the same signature

In most cases we use an implicit way .

Interface inheritance

Interface can be multiple inheritance, but it should be noted that, if the name explicitly implement an interface, you must first declare the interface.

namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Listing08_08
{
    interface IReadableSettingsProvider
    {
        string GetSetting(string name, string defaultValue);
    }

    interface ISettingsProvider : IReadableSettingsProvider
    {
        void SetSetting(string name, string value);
    }

Getting this method call is wrong:

  class FileSettingsProvider : ISettingsProvider,
        IReadableSettingsProvider
    {
        #region ISettingsProvider Members
        public void SetSetting(string name, string value)
        {
            // ...
        }
        #endregion

        #region IReadableSettingsProvider Members
         string ISettingsProvider.GetSetting(string name, string defaultValue)
        {
            return name + defaultValue; //just returning this for the example
        }
        #endregion
    }

}

It should be called with:

 string IReadableSettingsProvider.GetSetting(string name, string defaultValue)
        {
            return name + defaultValue; //just returning this for the example
        }

Interface multiple inheritance

Interfaces and classes, can inherit multiple interfaces:

namespace AddisonWesley.Michaelis.EssentialCSharp.Chapter08.Listing08_09
{
    interface IReadableSettingsProvider
    {
        string GetSetting(string name, string defaultValue);
    }

    interface IWriteableSettingsProvider
    {
        void SetSetting(string name, string value);
    }

    interface ISettingsProvider : IReadableSettingsProvider,
        IWriteableSettingsProvider
    {
    }
}

An Additional Extension Methods

Interface may also be used as a method of expansion, and more flexible, more practical than the class, and this method can be extended particular type, allows the collection of a particular type.

static class Listable
    {
        public static void List(
            this IListable[] items, string[] headers)
        {
            int[] columnWidths = DisplayHeaders(headers);

            for(int itemCount = 0; itemCount < items.Length; itemCount++)
            {
                if (items[itemCount] != null)
                {
                    string[] values = items[itemCount].ColumnValues;

                    DisplayItemRow(columnWidths, values);
                }
            }
        }
}

Interfaces and classes

A number of different interfaces and classes of comparison, uses it:
Here Insert Picture Description
recommended so use them:

  1. Generally preferred class rather than the interface. Abstract class separate contract (what type do) and implementation details (type how to do).
  2. If you need to make other types derived from the type of support interfaces defined function, consider the definition of the interface.

In fact, each has its advantages both a model is the angle a is the angle mechanism for a vertical a lateral direction.

Published 240 original articles · won praise 114 · views 180 000 +

Guess you like

Origin blog.csdn.net/sinat_33087001/article/details/103569596