C#入门详解(13)

为做基类而生的基类和开放/关闭原则

有上节继承开始引导,上代码

   public class Program
    {
        static void Main(string[] args)
        {
            Vehicle vehicle = new Car();
            vehicle.Stopped();
        }
    }

    public class Vehicle
    {
       public void Stopped()
        {
            Console.WriteLine("Stop it");
        }
    }

    class Car : Vehicle
    {
     public  void Run()
        {
            Console.WriteLine("B");
        }
    }

     class RaceCar :Vehicle
    {
        public void Run()
        {
            Console.WriteLine("C");
        }
    }

在代码中我们的vehicle实例只有stopped方法,而无法调用car里面的run方法,为了解决这个问题,我们有两种解决方案:

虚方法:

   public class Program
    {
        static void Main(string[] args)
        {
            Vehicle vehicle = new Car();
            vehicle.Run();
            Vehicle vehicle_ = new RaceCar();
            vehicle_.Run();
        }
    }

    public class Vehicle
    {
       public void Stopped()
        {
            Console.WriteLine("Stop it");
        }
       public virtual void Run()
        {
            Console.WriteLine("...");        }
    }

    class Car : Vehicle
    {
     public override void Run()
        {
            Console.WriteLine("B");
        }
    }

     class RaceCar :Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("C");
        }
    }

在基类中添加虚方法,让子类去重写,可有效解决这个问题。

在Vehicle加方法:

    public class Vehicle
    {
       public void Stopped()
        {
            Console.WriteLine("Stop it");
        }
        public void Run(string typename)
        {
            if (typename=="Car")
            {
                Console.WriteLine("B");
            }
            else if (typename == "RaceCar")
            {
                Console.WriteLine("C");
            }
        }
    }

违反了开闭原则,我们更改的类是关闭的,这个方法不行。

在上面两个方法中,我们采用虚方法这个解决方案,但不难发现,在实际工作中,我们可能永远不会调用Vehicle里面的Run方法,所以我们可以给他变成纯虚方法,使用关键字abstract,相应的类也变成了抽象类。

    public abstract class Vehicle
    {
       public void Stopped()
        {
            Console.WriteLine("Stop it");
        }
        public abstract void Run();
    }

当Vehicle里面的方法都为虚方法,它就是纯抽象类,这在C++比较常见,在C#中就是Interface,命名一般也以I开头

什么是接口和抽象类

接口和抽象类都是软件工程的产物

具体类-抽象类-接口:越来越抽象,内部实现的东西越来越少

抽象类是未完全实现的类,接口是完全未实现的类(可以有实现与未实现的成员和非public成员,它们代表了具体逻辑)

抽象类为复用而生:专门作为基类来使用,也具有解耦功能

封装确定的,开放不确定的,推迟到子类中实现

接口是完全未实现逻辑的“类”(纯虚类:只有函数成员;成员全部public)

接口为解耦而生:高内聚低耦合方便单元测试

接口是一个协约,早已为工业生产所熟知,有分工必有协作,有协作必有协约

它们都不能实例化,只能用来声明变量,引用具体类(concrete class)的实例

 

猜你喜欢

转载自www.cnblogs.com/jingjingweixiao/p/11074154.html