zoukankan      html  css  js  c++  java
  • 抽象类与接口的产生和使用

    我们以以下代码为例,简述一下抽象类与接口的由来和使用

        class Program
        {
            static void Main(string[] args)
            {
                Car car = new Car();
                car.Run();
                car.Stop();
                car.Fill();
            }
        }
        class Vehicle
        {
            public virtual void Run()
            {
                Console.WriteLine("Vehicle is Running");
            }
            public virtual void Stop()
            {
                Console.WriteLine("Vehicle is Stopped");
            }
            public virtual void Fill()
            {
                Console.WriteLine("Fill Fuel");
            }
        }
        class Car:Vehicle
        {
            public override void Run()
            {
                Console.WriteLine("Car is Running");
            }
            public override void Stop()
            {
                Console.WriteLine("Car is Stopped");
            }
        }
    }
    

    我们发现这个例子中,Vehicle类中的Run()和Stop()方法根本没有用到过,而且Vehicle is Running 这种说法太不具体了。
    因此我们修改Vehicle类,让Run()和Stop()方法里干脆啥都别写了,反正又用不到

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

    但是{}内空空的啥都不写这不合适吧,干脆把方法体也去掉吧,只留方法名
    以下这段代码无法通过编译,只是举例用

        class Vehicle
        {
            public virtual void Run() ;//这样是无法编译的
            public virtual void Stop() ;//这样是无法编译的
            public void Fill()
            {
                Console.WriteLine("Fill Fuel");
            }
        }
    

    Run()和Stop()方法本来就是虚方法(virtual),现在方法体也没了,更虚了,因此诞生了——抽象方法

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

    使用时,子类中重写依然是加个override就完事。
    抽象类是专门为了做基类而生的,因为抽象类无法实例化,即使抽象类内部有实际的方法,也因为有抽象方法而无法调用所有的方法而报错。
    即使有具体方法Fill(),依然不可以实例化。

    那么如果这个抽象类特别抽象,抽象到不含有任何实际方法,比如新建一个Vehicle类的父类Tools,具有抽象方法Fill()。

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

    在C#中,这种纯抽象类,就是接口。
    我们换成接口的写法:

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

    然后我们的代码就形成如下的层次:

    namespace Example
    {
    //程序执行入口
        class Program
        {
            static void Main(string[] args)
            {
                Car car = new Car();
                car.Run();
                car.Stop();
                car.Fill();
            }
        }
    //接口,把具体实现方法下放(放到基类)
        interface Tools
        {
            void Run();
            void Stop();
            void Fill();
        }
    //基类,把抽象的方法继续下方到派生(可能还是抽象类,也可能是具体类)
        abstract class Vehicle
        {
            abstract public void Run();
            abstract public void Stop();
            public virtual void Fill()
            {
                Console.WriteLine("Fill Fuel");
            }
        }
    //派生类(这里是具体类)把抽象方法补充成具体的方法
        class Car:Vehicle
        {
            override public void Run()
            {
                Console.WriteLine("Car is Running");
            }
    
            public override void Stop()
            {
                Console.WriteLine("Car is Stopped");
            }
        }
    }
    

    一般一个项目就是这样的架构,我们也了解了抽象类,接口等等的用法。

  • 相关阅读:
    iOS堆栈-内存-代码在据算机中的运行
    iOS self和super的区别
    php代码优化
    缓存雪崩现象解决方案
    缓存失效
    分布式memcache
    Linux下编译安装Memcache
    windows 下安装 php-memcached 扩展
    Linux下安装 php-memcache 扩展
    缓存之文件缓存
  • 原文地址:https://www.cnblogs.com/maomaodesu/p/11612580.html
Copyright © 2011-2022 走看看