2021-06-25-刘铁猛C#语言入门详解-学习笔记P27抽象类与开闭原则

P27抽象类与开闭原则

回溯记录:
2021/12/24回溯

一、P27内容总结
学前提要:SOLID
SLP 单一设计原则
OCP 开闭原则
LSP 替换原则
ILP 接口隔离原则
DSP 依赖反转原则

1.抽象类
2.开闭原则
3.接口
4.对抽象类、开闭原则与接口的总结

二、抽象类:函数成员没有被完全实现的类
抽象方法:函数没有被实现的方法,可以被子类实现

	//简单的抽象类&抽象方法,用abstract关键字修饰
	abstract class Student
    {
        abstract public void Study(); 
    }

三、开闭原则:函数成员没有被完全实现的类
封装一些不变的、稳定的、固定的成员,
不确定的、有可能改变的成员声明为抽象成员并且留给子类实现

不同类型的车“刹车”的方法相同,若在各种类型的车的类中繁琐的进行复制粘贴非常的麻烦
可以使用虚方法+重写的方式

//实例:为做基类而生的“抽象类”与“开放/关闭原则”(19:30开始讲解)
using System;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Vehicle v = new Car();
            v.Run();
        }
    }
    
    class Vehicle
    {
        public void Stop()
        {
            Console.WriteLine("Stopping");
        }
        
       public virtual void Run()
       {
            Console.WriteLine("Vehicle is running");
       };
    }
    
    class Car:Vehicle
    {
         public override void Run()
        {
            Console.WriteLine("Car is running");
        }
    }

    class Truck : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("Truck is running");
        }
    }

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

重写后车辆类的Run()方法永远实现不了
所以为方便把方法体去掉,即使用抽象方法(也叫纯虚方法)

//实例:为做基类而生的“抽象类”与“开放/关闭原则”(19:30开始讲解)
using System;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Vehicle v = new Car();
            v.Run();
        }
    }
    
    abstract class Vehicle
    {
        public void Stop()
        {
            Console.WriteLine("Stopping");
        }
        //这里不同于以往的重写,不需要加virtual关键字
       abstract public void Run();
    }
    
    class Car:Vehicle
    {
         public override void Run()
        {
            Console.WriteLine("Car is running");
        }
    }

    class Truck : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("Truck is running");
        }
    }

    class RaceCar : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("RaceCar is running");
        }
    }
}
//纯抽象类:就是抽象类中所有的成员都是抽象的
using System;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Vehicle v = new Car();
            v.Run(); 
        }
    }
    
    abstract class VehicleBase
    {
        abstract public void Stop();
        abstract public void Run();
    }

    abstract class Vehicle:VehicleBase
    {
        public override void Stop()
        {
            Console.WriteLine("Stopping");
        }
    }
    
    class Car:Vehicle
    {
         public override void Run()
        {
            Console.WriteLine("Car is running");
        }
    }

    class Truck : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("Truck is running");
        }
    }

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

四、接口
在C#中纯抽象类可替换为接口interface,对代码进行一些改写即可

using System;

namespace ConsoleApp3
{
    class Program
    {
        static void Main(string[] args)
        {
            Vehicle v = new Car();
            v.Run();
        }
    }
    
    //interface 代替纯抽象类
    interface IVehicle
    {
        void Stop();
        void Run();
    }

    //下一级,用抽象类进行一个不完全实现作为基类
    abstract class Vehicle:IVehicle
    {
        public void Stop()
        {
            Console.WriteLine("Stopping");
        }
        abstract public void Run();
    }

    //对具体类进行创建
    class Car:Vehicle
    {
         public override void Run()
        {
            Console.WriteLine("Car is running");
        }
    }

    class Truck : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("Truck is running");
        }
    }

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

五、对抽象类、开闭原则与接口的总结

  1. 抽象类是未完全实现的类P27
  2. 接口是完全未实现的类P27
  3. 抽象类是为复用而生,作为基类而使用(如实例中的Stop方法)P27
  4. 接口是为解耦而生P28
  5. 开闭原则:封装确定的,开放不确定的,推迟到合适的子类中实现P27
  6. 接口是一个“协约”P28
  7. 抽象类和接口都不能实例化,只能用于声明、引用具体的实例P27

(面试时):抽象基类abstract class与接口interface相同与区别
(1)相同:
抽象基类与接口均可被继承,不可被实例化;
(2)区别:
抽象基类是不完整的类需要进一步被细化,无法实现多继承,可为部分方法提供默认实现(提高代码可重用性),应用于共性较多的对象间寻求功能上的差异,例:鲤鱼、鲫鱼等鱼类这就是共性;
接口是行为上的规范即“协约”,可以实现多继承,接口中仅包含抽象方法,个性差异较大寻求共性时使用,例:人、鱼、青蛙虽然共性较弱但是个性(会游泳)较强。

你可能感兴趣的:(刘铁猛C#语言入门详解,c#)