抽象类与开闭原则、接口

本文通过C#代码示例展示了抽象类、接口的概念和用法,包括抽象类的定义、抽象方法,以及接口的实现和继承。强调了抽象类作为基类的角色和接口在实现多态及松耦合中的作用。同时,给出了接口继承的示例,说明如何通过接口来定义不同类型的车辆和武器行为。
摘要由CSDN通过智能技术生成
//抽象类具体例子
namespace Example027
{
	class Program
	{
		static void Main(string[] args)
		{
			//报错
			//Vehicle v = new Vehicle();		
			Vehicle v = new RaceCar();
			v.Run();					//事实上v.Stop()可以使用
		}
	}
	
	//有抽象方法必须得有抽象类
	abstract class Student
	{
		//抽象方法没有方法体 且 必须继承给子类(不能是private)
		abstract public void Study();
	}
}

  • 抽象类专为基类而生
namespace Example027
{
	class Program
	{
		static void Main(string[] args)
		{
			Console.WriteLine("Car is running...");
		}
	}

	abstract class Vehicle
	{
		public void Stop()
		{
			Console.WriteLine("Stopped!");
		}
		public void Fill()
		{
			Console.WriteLine("Pay and fill...");
		}
		public abstract 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...")
		}
	}
}

  • 接口
//接口
interface VehicleBase
{
	//接口里得方法必须是纯抽象类(就是没有方法体),以及必须是public,所以这两个都可以去掉
	//abstract public void Stop();
	void Stop();
	void Fill();
	void Run();
}

接口与单元测试

  • 接口的产生:自底向上(重构),自顶向下(设计)
  • C#中接口的实现(隐式,显式,多接口)
//接口的实际运用
namespace InterfaceExample
{
	class Program
	{
		static void Main(string[] args)
		{
			//求总数和平均值,如果没有接口,则需要写4个方法
			int[] nums1 = new int[]{1,2,3,4,5};
			ArrayList nums2 = new ArrayList{1,2,3,4,5};
	
			Console.WriteLine(Sum(nums1));
			Console.WriteLine(Avg(nums1));
			Console.WriteLine(Sum(nums2));
			Console.WriteLine(Sum(nums2));
		}
		
		//这里的IEnumerable相当于下面的IPhone,调用一个实例(抽象出来的),就可以完成相同操作。
		static int Sum(IEnumerable nums)
		{
			int sum=0;
			foreach(var n in nums)
				sum += (int)n;
			return sum;
		}
		
		static double Avg(IEnumerable nums)
		{
			int sum=0;
			double count = 0;
			foreach(var n in nums)
			{
				sum += (int)n;
				count++;
			}
			return sum/count;
		}
	}
}

接口的具体例子
将具体手机又抽象出一个类

namespace MyLib.MyNamespace2
{
    internal class Program
    {
        static void Main(string[] args)
        {
            var user = new PhoneUser(new NokiaPhone());
            user.UsePhone();
        }

        //接口
        interface IPhone
        {
            void Dail();
            void PickUp();
            void Send();
            void Receive();

        }
		
		//依赖关系(松耦合关系)
        class PhoneUser
        {
            private IPhone _phone;
            //一个接口实例
            public PhoneUser(IPhone phone)	!!!!!!最重要的一步
            {
                _phone = phone;
            }

            public void UsePhone()
            {
                _phone.Dail();
                _phone.PickUp();
                _phone.Send();
                _phone.Receive();
            }
        }

        class NokiaPhone : IPhone
        {
            public void Dail()
            {
                Console.WriteLine("Nokia calling...");
            }

            public void PickUp()
            {
                Console.WriteLine("Hello! This is Tim!");
            }

            public void Receive()
            {
                Console.WriteLine("Nokia message ring...");
            }

            public void Send()
            {
                Console.WriteLine("Hello!");
            }
        }

        class EricssonPhone : IPhone
        {
            public void Dail()
            {
                Console.WriteLine("Ericsson calling...");
            }

            public void PickUp()
            {
                Console.WriteLine("Hello! This is Tim!");
            }

            public void Receive()
            {
                Console.WriteLine("Ericsson message ring...");
            }

            public void Send()
            {
                Console.WriteLine("Good Evening!");
            }
        }

    }
}


  • 接口继承接口具体例子(一个接口可以有多个基接口、一个类只能有一个接口)
    解释:tank不属于IVehicle里面,但是又想只改变实例化对象
namespace MyLib.MyNamespace2
{
    public class Program
    {
        static void Main(string[] args)
        {
            var driver = new Driver(new HeavyTank());
            driver.Drive();
        }
    }

    class Driver
    {
        private IVehicle _vehicle;
        public Driver(IVehicle vehicle)
        {
            _vehicle = vehicle;
        }
        public void Drive()
        {
            _vehicle.Run();
        }
    }

    interface IVehicle
    {
        void Run();
    }

    class Car : IVehicle
    {
        public void Run()
        {
            Console.WriteLine("Car is running...");
        }
    }

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

    interface IWeapon
    {
        void Fire();
    }

    //一个接口对多个接口的继承
    interface ITank:IVehicle,IWeapon
    {
        /*
        void Fire();
        void Run();
        */
    }

    class LightTank : ITank
    {
        public void Fire()
        {
            Console.WriteLine("Boom!");
        }

        public void Run()
        {
            Console.WriteLine("ka ka ka......");
        }
    }

    class MediumTank : ITank
    {
        public void Fire()
        {
            Console.WriteLine("Boom!!");
        }

        public void Run()
        {
            Console.WriteLine("ka! ka! ka!......");
        }
    }

    class HeavyTank : ITank
    {
        public void Fire()
        {
            Console.WriteLine("Boom!!!");
        }

        public void Run()
        {
            Console.WriteLine("ka!! ka!! ka!!......");
        }
    }
}

抽象类与接口练习

总结:如果是静态类的集合可以使用接口,如果内部有一起用的属性,那么可以使用抽象类

internal class Program
    {
        // 使用接口输出老师和学生的姓名,工号,性别
        static void Main()
        {
            Teacher teacher = new Teacher() { name = "a",NO = 1,sex=gender.woman.ToString()};    
            Student student = new Student() { name = "b",NO = 2,sex=gender.man.ToString()};

            teacher.OutInformation();
            student.OutInformation();

            Console.ReadKey();
        }

        public abstract class IInformation
        {
            public string name;
            public int NO;
            public string sex;

            abstract public void OutInformation();
        }

        enum gender { man, woman };

        class Teacher : IInformation
        {
            public override void OutInformation()
            {
                Console.WriteLine($"我是一个Teacher,我叫{name},工号是{NO},性别是{sex}");
            }
        }

        class Student : IInformation
        {
            public override void OutInformation()
            {
                Console.WriteLine($"我是一个Student,我叫{name},工号是{NO},性别是{sex}");
            }
        }

    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值