里氏替换原则

1. 继承
    通过继承,子类会拥有父类的一切属性和行为
    父类出现的地方都可以由子类代替
    子类出现的地方不能由父类代替

    public class InheritTest
    {
         public static void Show()
        {
            {
                Console.WriteLine("*************************************");
                Parent  obj = new Parent();
                obj.CommonMethod();
                obj.VirtualMethod();
            }
            {
                Console.WriteLine("*************************************");
                Child obj = new Child();
                obj.CommonMethod();
                obj.VirtualMethod();
            }

            {
                Console.WriteLine("*************************************");
                //Child obj = new Parent(); obj是个子类,不可以赋值一个父类,子类出现的地方不能由父类代替
                Parent obj = new Child();//obj是个父类,可以赋值一个子类,因为父类出现的地方都可以由子类代替
                obj.CommonMethod();
                obj.VirtualMethod();

                /* D
                 A  都是Child
                 B. 都是Parent
                 C. common child,  virtual parent
                 D. common parent, virtual child
                  
                Parent obj = new Child();
                 普通方法的调用,由编译时决定,由左边决定(Parent)
                 虚方法/抽象方法的调用,由运行时决定, 由右边决定(Child)
               */
            }
            {
                Console.WriteLine("*************************************");
                AbstractParent obj = new AbstractChild();
                obj.AbstractMethod();
            }
            {
                Console.WriteLine("*************************************");
                AbstractChild obj = new AbstractGrand();
                obj.AbstractMethod();
            }
        }
    }

    public class Parent
    {
        public void CommonMethod()
        {
            Console.WriteLine("This is {0} CommonMethod1", this.GetType().Name);
        }
        public virtual void VirtualMethod()
        {
            Console.WriteLine("This is {0} VirtualMethod2", this.GetType().Name);
        }
    }

    public class Child:Parent
    {
        /// <summary>
        /// new 表示隐藏; 这这里有没有new都可以
        /// </summary>
        public new void CommonMethod()
        {
            Console.WriteLine("This is {0} CommonMethod3", this.GetType().Name);
        }
        /// <summary>
        /// override表示覆写
        /// </summary>
        public override  void VirtualMethod()
        {
            Console.WriteLine("This is {0} VirtualMethod4", this.GetType().Name);
        }
    }

    public abstract class AbstractParent
    {
        public abstract void AbstractMethod();
    }

    public class AbstractChild:AbstractParent
    {
        public override void AbstractMethod()
        {
            Console.WriteLine("This is {0} AbstractMethod1", this.GetType().Name);
        }
    }

    public class AbstractGrand:AbstractChild
    {
        public override void AbstractMethod()   //可以被override多次,这里用new就变成普通方法了
        {
            Console.WriteLine("This is {0} AbstractMethod2", this.GetType().Name);
        }
    }

 

2. 里氏替换原则(Liskov Substitution Principle LSP)
    A .所有使用基类的地方,都可以使用其子类来代替,而且行为不会有任何改变
    B. 如果子类不拥有父类的全部属性或者行为,不能继承,断掉继承
    C. 子类可以拥有父类没有的属性或者行为,子类出现的地方,父类不能代替

namespace LSP
{
    public class Chinese
    {
        public string Name { get; set; }
        public int Id { get; set; }
        public void Drink()
        {
            Console.WriteLine("{0}  中国人喜欢喝酒", this.GetType().Name);
        }
        public void Entertainment()
        {
            Console.WriteLine("{0}  中国人喜欢娱乐", this.GetType().Name);
        }
        public void EatFlour(Dumplings flour)
        {
            Console.WriteLine("{0}  中国人喜欢吃饺子", this.GetType().Name);
            flour.Taste();
        }
    }
}
namespace LSP
{
    public class Jiangxi:Chinese 
    {
        public string waguntang { get; set; } //瓦罐汤
        public void Larou()
        {
            Console.WriteLine("{0} 喜欢吃腊肉", this.GetType().Name);
        }

        //重载父类方法的时候要小心,很容易破坏里氏替换原则
        public void EatFlour(Flour flour) //重载
        {
            Console.WriteLine("{0} 喜欢吃所有面食", this.GetType().Name);
            flour.Taste();
        }
    }
}
    class Program
    {
        static void Main(string[] args)
        {
            try
            {
                Flour flour = new Flour();
                Dumplings dumplings = new Dumplings();
                Wonton wonton = new Wonton(); 

                {
                    Console.WriteLine("*************************************");
                    Chinese pepole = new Chinese();
                    pepole.Drink();
                    pepole.Entertainment();

                    //pepole.EatFlour(flour); //错误
                    pepole.EatFlour(dumplings);
                    pepole.EatFlour(wonton); 
                }
                {
                    Console.WriteLine("*************************************");
                    Chinese pepole = new Jiangxi();
                    pepole.Drink();
                    pepole.Entertainment();

                    //pepole.EatFlour(flour); //错误
                    pepole.EatFlour(dumplings);
                    pepole.EatFlour(wonton);
                }

                {
                    Console.WriteLine("*************************************");
                    Jiangxi pepole = new Jiangxi();
                    pepole.Drink();
                    pepole.Entertainment();

                    //这时候行为发生了改变,去调用子类的方法了,这个违背了里氏替换原则
                    pepole.EatFlour(flour);       
                    pepole.EatFlour(dumplings);
                    pepole.EatFlour(wonton);
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);
            }
            Console.ReadKey();
        }
    }
}

 

posted @ 2016-12-15 15:59  HepburnXiao  阅读(252)  评论(0编辑  收藏  举报