C#面向对象程序设计(7)

7.1 抽象类 

7.1.1 生活中的抽象类 

前面已经学习过类,知道类是对对象的抽象,那么抽象类可以看作是对类的抽象。抽象类的用途是提供一个可供多个派生类共享的通用基类定义 

7.1.2 抽象类的概念 

在面向对象思想中,所有的对象都可以通过类来描述。但并不是所有的类都是用来描绘对象的,如果一个类中没有包含足够能描述具体对象的信息,那么就称其为抽象类 

语法:

abstract class 类名 { } 

下面以电器充电的例子来说明抽象类 

示例:

class Computer: Appliance
{
        public override void Charge()
        {
	Console.WriteLine(" 电脑使用 220V 电压充电! ");
        }
}
class MobilePhone:Appliance
{
        public override void Charge()
        {
	Console.WriteLine(" 手机使用 110V 电压充电! ");
        }
}
abstract class Appliance
{
        public abstract void Charge();
}

static void Main(string[] args)
{
        Appliance cpt = new Computer();//父类引用指向子类对象
        Appliance mp = new MobilePhone();
        cpt.Charge();
        mp.Charge();
}

在 C# 中使用抽象类要注意以下几个要点 

  • 抽象类可以不包含抽象方法,但是含有抽象方法的类必须定义为抽象类 
  • 抽象方法不允许有方法体 
  • 子类继承于抽象类时必须重写抽象类中所有的抽象方法,除非子类也是抽象类 
  • 抽象类不允许直接实例化,只能实例化其非抽象子类对象 

7.1.3 抽象方法和虚方法的区别 

抽象方法和虚方法都是为了实现多态功能,其主要区别 

  1. 抽象方法只提供一个功能名称,要求子类必须实现该功能
  2. 虚方法不只提供功能名称还提供了默认实现方式,子类可以不重新实现该功能 

抽象方法:

  • 使用 abstract 关键字修饰 
  • 只能定义在抽象类中 
  • 不允许有方法体 
  • 子类必须重写

虚方法:

  • 使用 virtual 关键字修饰 
  • 可以定义在除密封类以外的类中
  • 必须有方法体
  • 子类可以重写

7.2 接口 

7.2.1 生活中的抽象类 

  • 日常生活中比较常见的接口有电源接口、电脑上的 USB 接口等
  • 在电源接口上接不同的电器可以使用不同的功能,比如接上冰箱就可以冷冻食物,接上电视机就可以观看电视节目,接上洗衣机就可以洗衣服 
  • 在电脑上也可以连接各种带 USB 接口的设备,比如连接摄像头、U 盘和鼠标等 

7.2.2 接口的概念 

C# 中子类最多只允许有一个父类。如果一个类需要具有多个类的特征或行为,那么可以通过接口来实现。C# 中的接口用于约束类的行为 

class Soldier
{
        public void Training()
        {
	Console.WriteLine(" 开始训练! ");
        }
}
class Actor
{
        public void Performance()
        {
	Console.WriteLine(" 开始表演! ");
        }
} 

class CivilianSoldier : Soldier, Actor//违反继承规则
{ 
}

修改上述示例,使用接口实现 

//定义士兵类和表演接口
class Soldier
{
        public void Training()
        {
	Console.WriteLine(" 开始训练! ");
        }
}
interface IPerformance
{
        void Show();
}
//继承类,并实现接口
class CivilianSoldier : Soldier, IPerformance
{
        public void Show()
        {
	Console.WriteLine(" 文艺兵在表演舞蹈! ");
        }
}
static void Main(string[] args)
{
//创建类的对象,调用继承的方法和通过接口实现的方法
        CivilianSoldier cs = new CivilianSoldier();
        cs.Training();
        cs.Show();
}

7.2.3 C#中的接口 

语法:

[ 访问修饰符 ] interface 接口名 { } 

注意:

  • 接口名一般使用大写字母“I”开头,表明它是接口类型 
  • 接口可包含方法、属性、事件和索引器,但不能包含字段 
  • 接口中定义的成员不允许有具体实现
  • 接口中的成员不允许加任何访问修饰符 

7.2.1 生活中的抽象类 

.NET 平台提供了非常多的接口 

7.2.2 接口的概念 

已知集合可提供排序方法对集合中的对象进行排序,但在集合中使用自定义类时则会出现类型未经处理的错误 

class Person
{
        private int age;
        public int Age
        {
	get { return age; }
	set { age = value; }
        }
       //其他属性及方法省略…
}
static void Main(string[] args)
{
        List<Person> list = new List<Person>();
        //初始化集合及循环显示代码省略…
        list.Sort();//调用集合中自带的排序方法
}

实现平台提供的 IComparable 接口,即可进行排序 

class Person: IComparable<Person>//实现平台自带接口
{
        // 其他代码略
        public int CompareTo(Person other)
        {
	return this.Age.CompareTo(other.Age);
        }
}

7.3 抽象类和接口的区别 

7.3.1 语法的区别 

在C# 中抽象类和接口在使用上有很多相同点,如两者都不能实例化,都可以包含未实现的方法,其子类必须实现其未实现的方法等,但是在定义时却有很大的区别 

抽象类 

接口

使用 abstract 关键字

使用 interface 关键字

可以包含字段和已实现成员

不能有字段,只能包含未实现的成员

子类通过 override 实现抽象方法   

子类直接实现所有成员

  1. 抽象类是一种特殊的类,不能被实例化,除此之外可以像普通类一样使用 
  2. 抽象类的用场合侧重于有继承关系的一组对象 
  3. 而接口用于定义一组行为规则,一般用于多个不同种类对象具有相同行为或功能的场合 

7.3.2 应用场合的区别 

抽象类使用场合示例 

//定义抽象类学生类
abstract class Student
{
        private string name;
        public string Name
        {
	get { return name; }
	set { name = value; }
        }
        public abstract void Sport();
}
//定义小学生类,继承学生类,实现抽象方法
class Pupil : Student
{
        public override void Sport()
        {
	Console.WriteLine(" 小学生参加短跑 200 米比赛! ");
        }
}
//定义大学生类,继承学生类,实现抽象方法
class Undergraduate : Student
{
        public override void Sport()
        {
                 Console.WriteLine(" 大学生参加足球比赛! ");
        }
}
//定义研究生类,继承学生类,实现抽象方法
class Postgraduate : Student
{
        public override void Sport()
        {
                  Console.WriteLine(" 研究生参加篮球比赛! ");
        }
}
static void Main(string[] args)
{
        Pupil stuOne = new Pupil(); //创建小学生、大学生、研究生对象
        Undergraduate stuTwo = new Undergraduate(); 
        Postgraduate stuThree = new Postgraduate(); 
        List<Student> list = new List<Student>();//定义学生类的集合,可以保存学生类的子类
        list.Add(stuOne);
        list.Add(stuTwo);
        list.Add(stuThree);
        foreach (Student stu in list)
        {
	stu.Sport();
        }
}

接口使用场合示例 

//定义推销员类和护士类,分别实现唱歌接口
class Salesman : ISing
{
         public void Sing()
         {
	Console.WriteLine(" 推销员开始演唱《映山红》。");
         }
}
class Nurse : ISing
{
         public void Sing()
         {
	Console.WriteLine(" 护士开始演唱《向天再借五百年》。");
         }
}


static void Main(string[] args)
{
        Salesman salesman = new Salesman();
        Nurse nurse = new Nurse();
        List<ISing> list = new List<ISing>();//定义集合,可以存储所有实现唱歌功能的对象
        list.Add(salesman);
        list.Add(nurse);
        foreach (ISing item in list)
        {
	item.Sing();
        }
}

//定义唱歌接口
interface ISing
{
        void Sing();
}

总结 

  1. 抽象方法只提供一个功能名称,要求子类必须实现该功能 
  2. 而虚方法不只提供功能名称还提供了默认实现方式,子类可以不重新实现该功能 
  3. 抽象类使用 abstract 关键字,可以包含字段和已实现成员,子类通过 override 实现抽象方法 
  4. 接口使用 interface 关键字,不能有字段,只能包含未实现的成员,子类直接实现所有成员

给TA打赏
共{{data.count}}人
人已打赏
C#

C#面向对象程序设计(6)

2022-8-15 19:02:18

C#

C#面向对象程序设计(8)

2022-8-16 19:12:04

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧
个人中心
今日签到
有新私信 私信列表
搜索