(设计模式学习笔记)四、里氏代换原则

一、里氏代换原则

1.定义

所有引用基类(父类)的地方必须能够透明地使用其子类的对象。

2.解析

有一个父类:

public abstract class A{}

有两个子类都继承父类A:

public class B:A{}
public class C:A{}

那么用里氏代换原则就可以:

A a=new B();
A a=new C();

但是不可以:

B b=new A();

例如有两个类,一个类为BaseClass,另一个是SubClass,并且BaseClass是SubClass的子类,那么一个方法如果可以接受一个BaseClass类型的基类对象base的话,如:method1(base),那么它必然可以接受一个BaseClass类型的子类对象sub,method1(sub)能够正常运行。反过来的代换不成立,如一个方法method2接受BaseClass类型的子类对象sub为参数:method2(sub),那么一般而言不可以有method2(base),除非是重载方法。

3.案例1

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _4.里氏代换原则
{
    class Program
    {
        public abstract class AbstractGun
        {
            public abstract void Shoot();

        }

        public class HandGun:AbstractGun
        {
            public override void Shoot()
            {
                Console.WriteLine("手枪射击。");
            }
        }

        public class Rifle : AbstractGun
        {
            public override void Shoot()
            {
                Console.WriteLine("步枪射击。");
            }
        }

        public class MachineGun : AbstractGun
        {
            public override void Shoot()
            {
                Console.WriteLine("机枪射击。");
            }
        }

        public class Solider
        {
            public void KillEnemy(AbstractGun gun)
            {
                Console.WriteLine("战士开始战斗。");
                gun.Shoot();
            }
        }

        public class ToyGun:AbstractGun
        {
            public override void Shoot()
            {
               Console.WriteLine("玩具射击。");
            }
        }

        public class G3:Rifle
        {
            public void ZoomOut()
            {
                Console.WriteLine("望远镜查看敌人。");
            }

            public void Shoot()
            {
                Console.WriteLine("G3射击。");
            }
        }

        public class Snipper
        {
            public void KillEnemy(G3 g3)
            {
                g3.ZoomOut();
                g3.Shoot();
            }
        }


        static void Main(string[] args)
        {
            Solider hero = new Solider();
            hero.KillEnemy(new ToyGun());


            Snipper hero01 = new Snipper();
            hero01.KillEnemy(new G3());

            Snipper hero02 = new Snipper();
            Rifle rifle = new Rifle();
            //hero02.KillEnemy((G3)rifle); //G3是Rifle的子类,Rifle是父类
            Console.ReadKey();



        }
    }
}

4.案例2

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace _5.里氏代换原则
{
    public class A
    {
        public virtual int Func(int x, int y)
        {
            return x + y;
        }
    }
    public class B:A
    {
        public override int Func(int x, int y)
        {
            return x-y;//违反了里氏替换原则,直接重写了父类的Func虚拟方法,引用父类的地方并不能透明的使用子类对象。
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            A a = new B();
            Console.WriteLine("10+5=" + a.Func(10, 5));
            Console.ReadKey();

        }
    }
}

输出结果为:10+5=5

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值