21.接口

21.面向对象-多态-接口


21.1 知识点

接口的概念

  • 接口是行为的抽象规范
  • 它也是一种自定义类型
  • 接口是类用来继承的
  • 关键字:interface

接口声明的规范

  • 不包含成员变量
  • 只包含方法、属性、索引器、事件
  • 成员不能被实现
  • 成员可以不写访问修饰符,不能是私有的
  • 接口不能继承类,但是可以继承另一个接口

接口的使用规范

  • 类可以继承多个接口
  • 类继承接口后,必须实现接口中所有成员

接口的特点

  • 类似于类的声明
  • 接口用来继承
  • 接口不能被实例化,但是可以作为容器存储对象

接口实际作用举例

  • 假设有个动物类 人和鸟继承动物类 但人不能飞 鸟可以飞 不能将飞这个行为抽象到动物类中
  • 但是可以写一个飞的接口 让鸟继承 人不继承
  • 这时 要是有个继承了机械类的飞机 也可以继承飞的接口

接口的声明

class语句块外namespace语句块内

// 接口关键字:interface
// 语法:
// interface 接口名
// {
// }
// 一句话记忆:接口是抽象行为的“基类”
// 接口命名规范:帕斯卡前面加个I

// 实例

// 飞翔接口
interface IFly
{
    // int f; // 报错,接口不包含成员变量

    // 方法,不能加方法体,不能被实现,默认是public
    void Fly();

    // 属性,get和set也不能有逻辑,不能被实现,默认是public
    string Name
    {
        get;
        set;
    }

    // 索引器,get和set也不能有逻辑,不能被实现,默认是public
    int this[int index]
    {
        get;
        set;
    }

    // 事件 
    event Action doSomthing;
}

接口的使用

class语句块外namespace语句块内

// 动物类
class Animal
{

}

// 1.类可以继承1个类,n个接口
class Person : Animal, IFly
{
    // 2.继承了接口后,必须实现其中的内容,并且必须是public的
    // 3.实现的接口函数,可以加virtual再在子类重写
    public virtual void Fly()
    {

    }

    public string Name
    {
        get;
        set;
    }

    public int this[int index]
    {
        get
        {
            return 0;
        }
        set
        {

        }
    }

    public event Action doSomthing;
}

接口可以继承接口

class语句块外namespace语句块内

// 接口继承接口时,不需要实现
// 待类继承接口后,类自己去实现所有内容

// 走路接口
interface IWalk
{
    void Walk();
}

// 移动接口,继承飞翔接口和走路接口
interface IMove : IFly, IWalk
{ 
}

// 移动测试类
class MoveTest : IMove
{
    // 因为移动接口继承飞翔接口和走路接口
    // 所以必须实现飞翔接口和走路接口里所有成员

    public int this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

    public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

    public event Action doSomthing;

    public void Fly()
    {
        throw new NotImplementedException();
    }

    public void Walk()
    {
        throw new NotImplementedException();
    }
}

主函数内

// 4.接口也遵循里氏替换原则
IMove imove1 = new MoveTest();
IFly ifly1 = new MoveTest();
IWalk iwalk1 = new MoveTest();

// 因为实际容器是IWalk,所以只能使用IWalk的成员Walk
iwalk1.Walk();
//(iwalk1 as MoveTest).Fly();//报错,因为实际容器是IWalk,不能使用飞翔相关
(iwalk1 as MoveTest).Fly(); // 强转后,可以使用飞翔相关

显示实现接口

class语句块外namespace语句块内

// 当一个类继承两个接口
// 但是接口中存在着同名方法时
// 注意:显示实现接口时不能写访问修饰符



// 攻击方法接口
interface IAttack
{
    void Attack();
}

// 超级攻击方法接口
interface ISuperAttack
{
    void Attack();
}

// 同时继承攻击方法接口和超级攻击方法接口
class Player : IAttack, ISuperAttack
{
    // 假如直接实现Attack,那么假如Player调用攻击
    // 无论容器是攻击接口还是超级攻击接口,都会是同个行为
    // 违背了接口抽象行为概念
    public void Attack()
    {
        Console.WriteLine("Player攻击");
    }

    // 显示实现接口可以解决接口同名成员问题
    // 显示实现接口就是用 接口名.行为名 去实现
    void IAttack.Attack()
    {
        Console.WriteLine("IAttack攻击");
    }

    void ISuperAttack.Attack()
    {
        Console.WriteLine("ISuperAttack攻击");
    }
}

主函数内

IAttack iAttack = new Player();
ISuperAttack iSuperAttack = new Player();

// 显示实现了接口,可以实现不同行为 
// 要是没有显示实现了接口,都会输出Player攻击
iAttack.Attack(); // IAttack攻击
iSuperAttack.Attack(); // ISuperAttack攻击

Player player = new Player();
(player as IAttack).Attack(); // IAttack攻击
(player as ISuperAttack).Attack(); // ISuperAttack攻击
player.Attack(); // Player攻击

总结

  • 继承类:是对象间的继承,包括特征行为等等

  • 继承接口:是行为间的继承,继承接口的行为规范,按照规范去实现内容

  • 由于接口也是遵循里氏替换原则,所以可以用接口容器装对象

  • 那么就可以实现装载各种毫无关系但是却有相同行为的对象

  • 注意:

    • 接口值包含 成员方法、属性、索引器、事件,并且都不实现,都没有访问修饰符
    • 可以继承多个接口,但是只能继承一个类
    • 接口可以继承接口,相当于在进行行为合并,待子类继承时再去实现具体的行为
    • 接口可以被显示实现,主要用于实现不同接口中的同名函数的不同表现
    • 实现的接口方法可以加 virtual 关键字,之后子类再重写

21.2 知识点代码

using System;

namespace Lesson19_多态_接口
{
    #region 知识点一 接口的概念
    //接口是行为的抽象规范
    //它也是一种自定义类型
    //接口是类用来继承的
    //关键字 :interface

    //接口申明的规范
    //1.不包含成员变量
    //2.只包含方法、属性、索引器、事件
    //3.成员不能被实现
    //4.成员可以不用写访问修饰符,不能是私有的
    //5.接口不能继承类,但是可以继承另一个接口

    //接口的使用规范
    //1.类可以继承多个接口
    //2.类继承接口后,必须实现接口中所有成员

    //特点:
    //1.它和类的申明类似
    //2.接口是用来继承的
    //3.接口不能被实例化,但是可以作为容器存储对象


    //接口实际作用举例:
    //假设有个动物类 人和鸟继承动物类 但人不能飞 鸟可以飞 不能将飞这个行为抽象到动物类中
    //但是可以写一个飞的接口 让鸟继承 人不继承
    //这时 要是有个继承了机械类的飞机 也可以继承飞的接口
    #endregion

    //class语句块外 namespace语句块内

    #region 知识点二 接口的申明
    //接口关键字:interface
    //语法:
    // interface 接口名
    // {
    // }
    //一句话记忆:接口是抽象行为的“基类”
    //接口命名规范 帕斯卡前面加个I

    //实例

    //飞翔接口
    interface IFly
    {
        //int ifly1;//报错 接口不包含成员变量

        //方法 不能加方法体 不能被实现 默认是public
        void Fly();
        //private void Fly2();//报错 接口不能是私有的

        //属性 get和set也不能有逻辑 不能被实现 默认是public
        string Name
        {
            get;
            set;
        }

        //索引器 get和set也不能有逻辑 不能被实现 默认是public
        int this[int index]
        {
            get;
            set;
        }

        //事件 
        event Action doSomthing;
    }

    #endregion

    #region 知识点三 接口的使用

    //动物类
    class Animal
    {

    }

    //1.类可以继承1个类,n个接口
    class Person : Animal, IFly
    {
        //2.继承了接口后 必须实现其中的内容 并且必须是public的
        //3.实现的接口函数,可以加virtual再在子类重写
        public virtual void Fly()
        {

        }

        public string Name
        {
            get;
            set;
        }

        public int this[int index]
        {
            get
            {
                return 0;
            }
            set
            {

            }
        }

        public event Action doSomthing;
    }


    #endregion

    #region 知识点四 接口可以继承接口

    //接口继承接口时  不需要实现
    //待类继承接口后  类自己去实现所有内容

    //走路接口
    interface IWalk
    {
        void Walk();
    }

    //移动接口 继承飞翔接口和走路接口
    interface IMove : IFly, IWalk
    { 
    }

    //移动测试类
    class MoveTest : IMove
    {
        //因为移动接口继承飞翔接口和走路接口
        //所以必须实现飞翔接口和走路接口里所有成员

        public int this[int index] { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public string Name { get => throw new NotImplementedException(); set => throw new NotImplementedException(); }

        public event Action doSomthing;

        public void Fly()
        {
           
        }

        public void Walk()
        {
            
        }
    }

    #endregion

    #region 知识点五 显示实现接口

    //当一个类继承两个接口
    //但是接口中存在着同名方法时
    //注意:显示实现接口时 不能写访问修饰符

    //攻击方法接口
    interface IAttack
    {
        void Attack();
    }

    //超级攻击方法接口
    interface ISuperAttack
    {
        void Attack();
    }

    //同时继承攻击方法接口和超级攻击方法接口
    class Player : IAttack, ISuperAttack
    {
        //假如直接实现Attack 那么假如Player调用攻击
        //无论容器是攻击接口还是超级攻击接口 都会是同个行为
        //违背了接口抽象行为概念
        public void Attack()
        {
            Console.WriteLine("Player攻击");
        }

        //显示实现接口可以解决接口同名成员问题
        //显示实现接口 就是用 接口名.行为名 去实现
        void IAttack.Attack()
        {
            Console.WriteLine("IAttack攻击");
        }

        void ISuperAttack.Attack()
        {
            Console.WriteLine("ISuperAttack攻击");
        }


    }


    #endregion
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("接口");

            //主函数内

            #region 知识点三 接口的使用

            //IFly ifly = new IFly();//报错 无法实例化接口

            //4.接口也遵循里氏替换原则
            //Person继承接口IFly 把接口当父类 父类装子类
            IFly ifly = new Person();


            #endregion

            #region 知识点四 接口可以继承接口

            //4.接口也遵循里氏替换原则
            IMove imove1 = new MoveTest();
            IFly ifly1 = new MoveTest();
            IWalk iwalk1 = new MoveTest();

            //因为实际容器是IWalk 所以只能使用IWalk的成员Walk
            iwalk1.Walk();
            //iwalk1.Fly();//报错 因为实际容器是IWalk 不能使用飞翔相关
            (iwalk1 as MoveTest).Fly();//强转后 可以使用飞翔相关

            #endregion

            #region 知识点五 显示实现接口

            IAttack iAttack = new Player();
            ISuperAttack iSuperAttack = new Player();

            //显示实现了接口 可以实现不同行为 
            //要是没有显示实现了接口 都会输出Player攻击
            iAttack.Attack();//IAttack攻击
            iSuperAttack.Attack();//ISuperAttack攻击

            Player player = new Player();
            (player as IAttack).Attack();//IAttack攻击
            (player as ISuperAttack).Attack();//ISuperAttack攻击
            player.Attack();//Player攻击

            #endregion
        }
    }

    //总结:

    //继承类:是对象间的继承,包括特征行为等等
    //继承接口:是行为间的继承,继承接口的行为规范,按照规范去实现内容
    //由于接口也是遵循里氏替换原则,所以可以用接口容器装对象
    //那么久可以实现 装载各种毫无关系但是却有相同行为的对象

    //注意:
    //1.接口值包含 成员方法、属性、索引器、事件,并且都不实现,都没有访问修饰符
    //2.可以继承多个接口,但是只能继承一个类
    //3.接口可以继承接口,相当于在进行行为合并,待子类继承时再去实现具体的行为
    //4.接口可以被显示实现 主要用于实现不同接口中的同名函数的不同表现
    //5.实现的接口方法 可以加 virtual关键字 之后子类 再重写
}

21.3 练习题

人、汽车、房子都需要等级,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记 使用接口实现登记方法

class语句块外 namespace语句块内

// 登记接口
interface IRegister
{
    void Register();
}

// 人类
class Person : IRegister
{
    public void Register()
    {
        Console.WriteLine("派出所登记");
    }
}

// 车类
class Car : IRegister
{
    public void Register()
    {
        Console.WriteLine("车管所登记");
    }
}

// 房子类
class House : IRegister
{
    public void Register()
    {
        Console.WriteLine("房管局登记");
    }

主函数内

// 主函数内
IRegister[] IRegisterArray = new IRegister[] { new Person(), new House(), new Car() };

for (int i = 0; i < IRegisterArray.Length; i++)
{
    IRegisterArray[i].Register();
}

麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅

  • 直升机和部分鸟能飞
  • 鸵鸟和企鹅不能飞
  • 企鹅和天鹅能游泳
  • 除直升机,其它都能走
  • 请用面向对象相关知识实现

class语句块外 namespace语句块内

// 鸟类
abstract class Bird
{
    // 鸟都能能走
    public abstract void Walk();
}

// 飞行接口
interface IFly
{
    void Fly();
}

// 游泳接口
interface ISwimming
{
    void Swimming();
}

// 麻雀类
class Sparrow : Bird, IFly
{
    public void Fly()
    {

    }

    public override void Walk()
    {

    }
}

// 鸵鸟类
class Ostrich : Bird
{
    public override void Walk()
    {

    }
}

// 企鹅类
class Penguin : Bird, ISwimming
{
    public void Swimming()
    {

    }

    public override void Walk()
    {

    }
}

// 鹦鹉类
class Parrot : Bird, IFly
{
    public void Fly()
    {

    }

    public override void Walk()
    {

    }
}

// 天鹅类
class Swan : Bird, IFly, ISwimming
{
    public void Fly()
    {

    }

    public void Swimming()
    {

    }

    public override void Walk()
    {

    }
}

// 直升机类
class Helicopter : IFly
{
    public void Fly()
    {

    }
}

多态来模拟移动硬盘、U盘、MP3查到电脑上读取数据

  • 移动硬盘与U盘都属于存储设备
  • MP3属于播放设备
  • 但他们都能插在电脑上传输数据
  • 电脑提供了一个USB接口
  • 请实现电脑的传输数据的功能

class语句块外 namespace语句块内

// USB接口
interface IUSB
{
    void ReadData();
}

// 存储设备类
class StorageDevice : IUSB
{
    public string name;

    public StorageDevice(string name)
    {
        this.name = name;
    }

    public void ReadData()
    {
        Console.WriteLine("{0}传输数据", name);
    }
}

// MP3类
class MP3 : IUSB
{
    public void ReadData()
    {
        Console.WriteLine("MP3传输数据");
    }
}

// 电脑类
class Computer
{
    // 电脑有一个USB接口 外部给他赋值 相当于插到电脑上
    public IUSB usb1;
}

主函数内

// 主函数内
StorageDevice moveDevice = new StorageDevice("移动硬盘");
StorageDevice uDevice = new StorageDevice("U盘");
MP3 mp3 = new MP3();

Computer computer = new Computer();

computer.usb1 = moveDevice;
computer.usb1.ReadData();//移动硬盘传输数据

computer.usb1 = uDevice;
computer.usb1.ReadData();//U盘传输数据

computer.usb1 = mp3;
computer.usb1.ReadData();//MP3传输数据


21.4 练习题代码

using System;

namespace Lesson19_练习题
{
    //class语句块外 namespace语句块内

    #region 练习题一
    //人、汽车、房子都需要登记,人需要到派出所登记,汽车需要去车管所登记,房子需要去房管局登记
    //使用接口实现登记方法

    //登记接口
    interface IRegister
    {
        void Register();
    }

    //人类
    class Person:IRegister
    {
        public void Register()
        {
            Console.WriteLine("派出所登记");
        }
    }

    //车类
    class Car:IRegister
    {
        public void Register()
        {
            Console.WriteLine("车管所登记");
        }
    }

    //房子类
    class House:IRegister
    {
        public void Register()
        {
            Console.WriteLine("房管局登记");
        }
    }

    #endregion

    #region 练习题二
    //麻雀、鸵鸟、企鹅、鹦鹉、直升机、天鹅
    //直升机和部分鸟能飞
    //鸵鸟和企鹅不能飞
    //企鹅和天鹅能游泳
    //除直升机,其它都能走
    //请用面向对象相关知识实现

    //鸟类
    abstract class Bird
    {
        //鸟都能能走
        public abstract void Walk();
    }

    //飞行接口
    interface IFly
    {
        void Fly();
    }

    //游泳接口
    interface ISwimming
    {
        void Swimming();
    }

    //麻雀类
    class Sparrow : Bird, IFly
    {
        public void Fly()
        {
           
        }

        public override void Walk()
        {
            
        }
    }

    //鸵鸟类
    class Ostrich:Bird
    {
        public override void Walk()
        {

        }
    }

    //企鹅类
    class Penguin : Bird,ISwimming
    {
        public void Swimming()
        {
            
        }

        public override void Walk()
        {

        }
    }

    //鹦鹉类
    class Parrot : Bird,IFly
    {
        public void Fly()
        {
            
        }

        public override void Walk()
        {

        }
    }

    //天鹅类
    class Swan : Bird,IFly,ISwimming
    {
        public void Fly()
        {
            
        }

        public void Swimming()
        {
            
        }

        public override void Walk()
        {

        }
    }

    //直升机类
    class Helicopter : IFly
    {
        public void Fly()
        {
            
        }
    }

    #endregion

    #region 练习题三
    //多态来模拟移动硬盘、U盘、MP3查到电脑上读取数据
    //移动硬盘与U盘都属于存储设备
    //MP3属于播放设备
    //但他们都能插在电脑上传输数据
    //电脑提供了一个USB接口
    //请实现电脑的传输数据的功能

    //USB接口
    interface IUSB
    {
        void ReadData();
    }

    //存储设备类
    class StorageDevice : IUSB
    {
        public string name;
        public StorageDevice(string name)
        {
            this.name = name;
        }

        public void ReadData()
        {
            Console.WriteLine("{0}传输数据", name);
        }
    }

    //MP3类
    class MP3 : IUSB
    {
        public void ReadData()
        {
            Console.WriteLine("MP3传输数据");
        }
    }

    //电脑类
    class Computer
    {
        //电脑有一个USB接口 外部给他赋值 相当于插到电脑上
        public IUSB usb1;
    }

    #endregion


    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("接口练习题");

            //主函数内

            #region 练习题一

            IRegister[] IRegisterArray = new IRegister[] { new Person(), new House(), new Car() };

            for (int i = 0; i < IRegisterArray.Length; i++)
            {
                IRegisterArray[i].Register();
            }

            #endregion

            #region 练习题三

            StorageDevice moveDevice = new StorageDevice("移动硬盘");
            StorageDevice uDevice = new StorageDevice("U盘");
            MP3 mp3 = new MP3();

            Computer computer = new Computer();

            computer.usb1 = moveDevice;
            computer.usb1.ReadData();//移动硬盘传输数据

            computer.usb1 = uDevice;
            computer.usb1.ReadData();//U盘传输数据

            computer.usb1 = mp3;
            computer.usb1.ReadData();//MP3传输数据

            #endregion

        }
    }
}


转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏