C#学习(13)-----抽象类与开闭原则

开闭原则:如果不是为了修改bug或者优化/增添功能,不要乱改一个类的代码。

即,应该封装那些稳定的固定的确定的成员,把不确定的成员作为抽象成员,给子类实现。

一开始,为了减少重复代码和尽量减少对类的修改,引入了基类。

    class Vehicle
    {
        private int _speed;
        public virtual int Speed { get { return _speed; } set { _speed = value; } }
        public void Fill()
        {
            Console.WriteLine("Add oil......");
        }
        public void Stop()
        {
            Console.WriteLine("Stopped......");
        }
        public virtual void Run()
        {
            Speed += 100;
            Console.WriteLine("A vehicle is running!");
        }
    }

    class Car : Vehicle
    {
        private int _rpm;
        public override int Speed { get { return _rpm / 100; } set { _rpm = value * 1000; } }
        public override void Run()
        {
            _rpm += 5000;
            Console.WriteLine("A car is running!");
        }
    }

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

后来,又因为基类的那个原来的方法也从不调用,为了减少维护代价,增加代码可读性,引入抽象类:

    abstract class Vehicle
    {
        ……
        public abstract void Run();
    }

抽象类事例如上。

抽象类是指函数成员没有被完全实现的类。类里面一旦有了抽象成员,类整体就必须用abstract修饰。抽象类不能实例化,故而,抽象类只能作为基类来派生子类,或者用于引用子类的实例。

抽象类的抽象成员最终一定由其子类实现,故函数成员不能是private。

其中,由子类实现,指的是在继承链上实现即可,没有要求其中某一个子类必须实现所有抽象的成员。

但是必须在缺少的子类前面加一个abstract。

也有全部成员都抽象的抽象类。

    abstract class VehicleBase
    {
        public abstract void Fill();
        public abstract void Stop();
        public abstract void Run();
    }
    abstract class Vehicle : VehicleBase
    {
        public override void Fill()
        {
            Console.WriteLine("Add oil......");
        }
        public override void Stop()
        {
            Console.WriteLine("Stopped......");
        }
    }

这时候这个玩意就相当于接口,甚至可以直接改成接口。只需把:

    abstract class VehicleBase
    {
        public abstract void Run();
        public abstract void Fill();
        public abstract void Stop();
    }

改成

    interface IVehicle
    {
        void Run();
        void Fill();
        void Stop();
    }

且删除下面所有的override即可,并且在缺斤少两的类中加一句:

    interface IVehicle
    {
        void Fill();
        void Stop();
        void Run();
    }
    abstract class Vehicle : IVehicle
    {
        public void Fill()
        {
            Console.WriteLine("Add oil......");
        }
        public void Stop()
        {
            Console.WriteLine("Stopped......");
        }
        abstract public void Run();
    }

    class Car : Vehicle
    {
        public override void Run()
        {
            Console.WriteLine("A car is running!");
        }
    }
}

接口里面的成员全都是抽象且公开的。

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

从具体类到抽象类再到接口,代码形式越来越抽象,内部实现的逻辑越来越少。

抽象类是未完全实现功能的类,可以有字段和非public成员,代表了“具体逻辑”。

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

它体现了开闭原则:封装确定的,开放不确定的,推迟到合适的子类中去实现。

而接口是完全未实现逻辑的“类”(纯虚类)

接口为解耦而生。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值