3-10 抽象

Profile Picture
- Published on Mar 10, 2020🌏 Public

面向对象 抽象

抽象方法和抽象属性,必须卸载抽象类类。

抽象类不能算是一个完整的类,因为抽象类类的抽象属性和抽象方法,都没有具体的实现代码。

抽象不能被实例化,只可以作为其他类的父类进行使用。

    class Program
    {
        static void Main()
        {
            var w = new M16();
            w.Area = "2km";
            w.OpenFire();
            ((Weapon)w).OpenFire();
        }
    }

    class M16 : Weapon
    {
        public override string Area { 
            get;
            set;
        }
        public override void OpenFire()
        {
            Console.WriteLine("开火,火力范围" + Area);
            Console.ReadKey();
        }
    }

    abstract class Weapon
    {
        public abstract void OpenFire();
        public abstract string Area
        {
            get;
            set;
        }
    }

所有的抽象方法和抽象属性,只能写在抽象类类。

能否实例化能否继承方法和属性有没有代码主体重写方式
virtual所在的类可以实例化所在类可以被继承根据需要使用override重写
abstract无法实例化可以继承×强制要求继承抽象类的子类必须重写所有抽象内容

面向对象 接口

类只能继承一个父类(包括抽象类),但是他可以继承多个接口。

接口是功能的抽象定义。

比如我们有猫、车、杯子三种完全无关类型。我们定义一个武器接口后,可以为这三个类都加上武器接口。

加上武器接口后,这三个类就都有了开火的功能。并且我们可以把他们都存在一个列表中,以武器接口类型去进行调用,从而用for以武器接口类型调用开火。这样的好处是我们可以把关注点移到功能上,而不再考虑数据类型到底是什么。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Threading;

namespace Test4
{
    class Program
    {
        static void Main()
        {
            var car = new Car();
            var cat = new Cat();
            var cup = new Cup();
            List<IWeapon> list = new List<IWeapon>();
            list.Add(car);
            list.Add(cat);
            list.Add(cup);
            foreach (IWeapon item in list)
            {
                item.OpenFire();
            }
            Console.ReadKey();
        }
    }

    public class Cup : IWeapon,IDie
    {
        public string WeaponName { get; set; }

        public void GoToDie()
        {
            Console.WriteLine("杯子碎了");
        }

        public void OpenFire()
        {
            Console.WriteLine("投掷攻击");
        }
    }

    public class Cat : Animal, IWeapon
    {
        public string WeaponName { get; set; }
        public void OpenFire()
        {
            Console.WriteLine("猫猫爪击");
        }
    }

    public class Car : Carrier, IWeapon
    {
        public string WeaponName { get; set; }

        public void OpenFire()
        {
            Console.WriteLine("汽车人变形");
        }
    }

    /// <summary>
    ///     武器接口
    /// </summary>
    public interface IWeapon
    {
         string WeaponName { get; set; }
         void OpenFire();
    }

    /// <summary>
    ///     死亡接口
    /// </summary>
    public interface IDie
    {
        void GoToDie();
    }

    public class Carrier
    {
        public void Run() {
            Console.WriteLine("开动");
        }
    }

    public class Animal
    {
        public virtual void Talk()
        {
            Console.WriteLine("打招呼");
        }
    }
}
<table> <tr><th></th><th>接口</th><th>抽象类</th><tr> <tr><td>关键词</td><td>Interface</td><td>abstract</td></tr> <tr><td>子类继承</td><td>一个子类可以继承多个接口</td><td>一个子类只能继承一个父类</td></tr> <tr><td>子类的实现</td><td>不要override,直接写就行</td><td>通过override重写</td></tr> <tr><td>方法的定义</td><td colspan="2">只要定义,不需要具体代码块,具体代码实现在子类中进行</td></tr> <tr><td>属性的定义</td><td colspan="2">自定义属性的get/set访问器的存在,访问器的具体代码在子类中实现</td></tr> <tr><td>实例化</td><td colspan="2">不能实例化</td></tr> </table>

练习

  1. 抽象类 Carrier 载具,他有抽象方法Run,正常属性Name载具名。

  2. 逃生系统接口 IEscape , 有一个Escape方法;

  3. 武器系统 IWeapon,有OpenFire方法和Reload方法。

  4. 建立三个载具的子类,Car,Boat,Plane,继承载具。

  5. 建立若干个具体的类(具体车船飞机型号),继承自Car、Boat和Plane,根据实际情况,为这些类选择性的继承武器和逃生接口。

  6. 建立Carrier列表,以及IEscape和IWeapon的两个列表,把建立的实例丢到列表中。

  7. 对于载具列表,显示"XXX起航"/"XXX起飞"/"XXX启动",武器调用Reload和OpenFire,逃生设备,调用Escape;