《C# 语言入门详解(刘铁锰) - 学习笔记 - 接口与抽象类》

文章目录

  • 前言
  • 一、接口是什么?
    • 1. 基础概念
    • 2. 声明与实现
  • 二、抽象类是什么?
    • 1. 基本概念
    • 2. 开闭原则
  • 三、抽象类与接口
    • 1. 联系
    • 2. 区别
    • 3. 成员派生关系


前言

  • 接口(Interface): 是一种契约(或者说是规范),可定义方法属性索引器事件,但不能设置具体值;
  • 接口为解耦而生(”高内聚,低耦合“,方便单元测试);
  • 接口所定义的属性、方法,继承时需全部实现。
  • 抽象类(Abstract): 函数成员没有被完全实现的类(不允许实例化、可作为基类被派生);
  • 一个抽象类可以包含抽象和非抽象方法,当一个类继承于抽象类,那么这个派生类必须实现所有的
    的基类抽象方法;
  • 抽象类能够继承非抽象类,另外,继承了基类的方法,添加新的抽象和非抽象方法是可行的;
  • 不能把关键字abstract 和 sealed 一起用在C#中,因为一个密封类不能够被抽象

一、接口是什么?

1. 基础概念

  • 定义: 是一种规范,用来声明变量,不能实例化,其所声明的变量,在继承时,需全部实现
  • 语法:
    (【修饰符】)interface 【接口名称】(:【继承的接口列表】)
    {
    接口内容
    }
  • 实现:
// 声明接口
 interface IInformation
    {
        string Code {get;set;}	//声明属性
        void ShowInfo();	//声明方法
    }

// 继承接口
public class AInfo : IInformation
    {
        string _code;
        public string Code
        {
			get {return _code;}
			set {_code =  value;}		
		}
        public void ShowInfo()
        {
            Console.WriteLine("编码:"+ Code);
        }
    }

// 实现接口
public void main()
{
	IInformation info = new AInfo();
	info.Code = "001";
	info.ShowInfo();
}

===> 编码:001

2. 声明与实现

  • 显式接口: 解决两个接口包含相同的成员,但两个接口成员实现不同的功能,无法直接调用的问题。(语法: 接口名称+句号命名该类成员(Information.Code))
interface Information1
{
	string Code {get;set;}
	void ShowInfo();
}

interface Information2
{
	string Code {get;set;}
	void ShowInfo();
}

public class AInfo : Information1, Information2
{
	string _code;
	public string Information1.Code		//	显示接口,继承Information1的成员
	{
		get {return _code;}
		set {_code = value;}
	}
}

注意事项:

  • 接口只能包含非静态成员函数(方法,属性,事件,索引器);
  • 接口只用于声明变量,这些函数成员不能包含任何实现的代码,而且主体后面必须使用分号;
  • 按照管理,接口的声明,必须使用大写 I 开头;
  • 接口声明可以带任何修饰符。例如 public protected internal private。但是 接口的成员,都是隐式的public ,不能带任何修饰符 ,包括 public。
  • 如果类实现了接口,那么它必须要实现接口的所有成员。

二、抽象类是什么?

1. 基本概念

  • 定义: 函数成员没有被完全实现的类(不允许实例化、可作为基类被派生);
  • 实现:
using System;

namespace Csharp
{
    class Program
    {
        static void main(string[] args)
        {
            Vehicle v = new Car();  //基类成员子类实例化
            v.Run();
            v.Stop();
        }
    }

    //抽象类,基类成员可被派生,抽象类不允许实例化,但可以作为基类对子类成员实例化
    abstract class Vehicle 
    {
        public abstract void Run(); //抽象成员,不执行

        public virtual void Stop()
        {
            Console.WriteLine("Stopped!");
        }
    }

    class Car : Vehicle
    {
        //重写基类run方法,子类override修饰,父类virtual修饰
        public override void Run()
        {
            Console.WriteLine("Car is running...");
        }
    }

   
}
  • 与接口结合实现:
using System;

namespace Csharp
{
    class Program
    {
        static void main(string[] args)
        {
            Vehicle v = new Car();  //基类成员子类实例化
            v.Run();
            v.Fill();
            v.Stop();
            IVehicle info = new Truck(); //接口派生类(子类)的实例化
            info.Fill();
            info.Run();
        }
    }

    //接口,定义两个方法run、fill
    interface IVehicle
    {
        void Run();
        void Fill();
    }

    //抽象类,基类成员可被派生,抽象类不允许实例化,但可以作为基类对子类成员实例化
    abstract class Vehicle : IVehicle
    {
        public abstract void Run(); //抽象成员,不执行

        public void Fill()
        {
            Console.WriteLine("Pay and fill...");
        }

        public virtual void Stop()
        {
            Console.WriteLine("Stopped!");
        }
    }

    class Car : Vehicle
    {
        //重写基类run方法,子类overrid修饰,父类virtual修饰
        public override void Run()
        {
            Console.WriteLine("Car is running...");
        }
    }

    //Truck类,继承自接口
    class Truck : IVehicle
    {
        public void Run()
        {
            Console.WriteLine("Truck is running...");
        }
        public void Fill()
        {
            Console.WriteLine("Truck Pay and fill...");
        }
    }
}

2. 开闭原则

定义:

  1. 软件实体应当对扩展开放、对修改关闭。
  2. 当应用的需求发生改变时,在不修改软件实体的源代码和二进制代码的前提下,可以扩展模块的功能,使其满足新的需求。
  3. 软件实体包含:项目中划分的模块,类与接口、方法。

作用:

  1. 提高代码的复用性;
  2. 提高软件的可维护性。

实现:

  1. 通过 “抽象约束、封装变化” 来实现开闭原则(即通过接口或者抽象类为软件定义一个相对稳定的抽象层,而将可变因素封装在相同的具体实现类中);
  2. 抽象灵活性好,适应性广,只要抽象的合理,可以基本保持软件架构的稳定,故而常根据需求重新派生一个实现类来实现开闭原则。

三、抽象类与接口

1. 联系

  1. 两者均不能实例化,只能用来声明变量;
  2. 两者的派生类只能继承一个基类(即,只能继承一个抽象类,可继承任意多个接口)

2. 区别

  1. 抽象类为复用而生(即,专门作为基类来使用,也具有解耦的功能);接口专门为解耦而生(即,”高内聚,低耦合“,方便单元测试)
  2. 抽象类中可定义成员的实现,而接口不行;
  3. 抽象类中可包含字段、构造函数、析构函数、静态成员或常量等,接口不可以;
  4. 抽象类中的成员可以是私有的、内部的、受保护的,但接口成员默认是公共的,定义时不能加修饰符;
  5. 抽象类是未完全实现的逻辑类(即,可以有字段和非public成员,它们代表具体逻辑);接口是完全未实现的逻辑类(即,”纯虚类“,只有函数成员,成员全部public)

3. 成员派生关系

《C# 语言入门详解(刘铁锰) - 学习笔记 - 接口与抽象类》_第1张图片

你可能感兴趣的:(学习笔记,c#,抽象类,接口)