对VC#.NET面向对象多态性问题研究

时间:2022-10-27 05:19:31

对VC#.NET面向对象多态性问题研究

摘要:在VC#.net程序设计中,面向对象程序设计难点和重点是对多态性的理解和掌握。如:接口与抽象类,类和结构体,覆写与重载等,它们有许多的相同点与不同点,在软件开中如何区别和运用,该文一一作了深究。

关键词:VC#.NET;面向对象程序;多态性

中图分类号:TP311文献标识码:A文章编号:1009-3044(2011)18-4379-04

On VC#.NET Object-oriented Polymorphism Issues

WU Ping-gui

(Chongqing Zhengda Software Institute Banan District, Chongqing 400056, China)

Abstract: In VC#.net programming, object-oriented programming difficulties and the focus is on understanding and grasp of polymorphism. Such as: interfaces and abstract classes, classes and structures, overriding and overloading, etc., they have many similarities and differences, differences in how software development and use, this one by the bottom.

Key words: VC#.NET; object-oriented program; polymorphism

1 接口和抽象类

1.1 接口

接口是一组行为的集合,其中每一种方法都有其名称、参数和返回值。接口方法不能包含任何实现,CLR 允许接口可以包含事件、属性、索引器、静态方法、静态字段、静态构造函数以及常数。C# 中的接口不能包含任何静态成员。一个类可以实现多个接口,当一个类继承某个接口时,它不仅要实现该接口定义的所有方法,还要实现该接口从其他接口中继承的所有方法。

代码实现字符串大小写转换,如下:

public interface convertChar //声明convertChar为一个接口

{

string lowerString(string str);//将所有的字符转换为小写。

}

public class LowerTest : convertChar//LowerTest从convertChar中去继承

{

public string lowerString(string str)//实现接口中的方法

{

returnstr.ToLower();

}

}

1.2 抽象类

抽象类提供多个派生类共享基类的公共定义,它既可以提供抽象方法,也可以提供非抽象方法。抽象类不能实例化,必须通过继承由派生类实现其抽象方法,因此对抽象类不能使用new 关键字,也不能被密封。如果派生类没有实现所有的抽象方法,则该派生类也必须声明为抽象类。另外,实现抽象方法由overriding 方法来实现。其代码如下:

abstract public class Person

{

protected string _perID;//定义字段

public abstract string _id { get; set; }//定义属性

public abstract void Ead();//定义方法

}

public class student : Person//学生类从抽象基类 Person中继承

{

public override string _id

{

get

{

return _perID;

}

set

{

_perID = value;

}

}

public override void Ead()

{

Console.Write("小张正在午餐") ;

}

}

1.3 相同点与不同点

1.3.1 相同点

接口与抽象类都不能被直接实例化,可以通过继承实现其抽象方法。

1.3.2 不同点

接口支持多继承;抽象类不能实现多继承;接口只能定义抽象规则;抽象类既可以定义规则,还可能提供已实现的成员;接口是一组行为规范;抽象类是一个不完全的类,着重族的概念;接口可以用于支持回调;抽象类不能实现回调,因为继承不支持;接口只包含方法、属性、索引器、事件的签名,但不能定义字段和包含实现的方法;抽象类可以定义字段、属性、包含有实现的方法。 接口可以作用于值类型和引用类型;抽象类只能作用于引用类型。例如,Struct 就可以继承接口,而不能继承类。

1.3.3 规则与场合

请记住,面向对象思想的一个最重要的原则就是:面向接口编程。借助接口和抽象类,23 个设计模式中的很多思想被巧妙的实现了,我认为其精髓简单说来就是:面向抽象编程。抽象类应主要用于关系密切的对象,而接口最适合为不相关的类提供通用功能。接口着重于CAN-DO 关系类型,而抽象类则偏重于IS-A 式的关系; 接口多定义对象的行为;抽象类多定义对象的属性;接口定义可以使用public 、protected 、internal 和private 修饰符,但是几乎所有的接口都定义为public ,原因就不必多说了。“接口不变” ,是应该考虑的重要因素。所以,在由接口增加扩展时,应该增加新的接口,而不能更改现有接口。向接口中添加新成员则会强制要求修改所有派生类,并重新编译,所以版本式的问题最好以抽象类来实现。从抽象类派生的非抽象类必须包括继承的所有抽象方法和抽象访问器的实实现。对抽象类不能使用new 关键字,也不能被密封,原因是抽象类不能被实例化。在抽象方法声明中不能使用 static 或 virtual 修饰符。

2 类与结构

2.1 什么是类

class (类)是面向对象编程的基本概念,是一种自定义数据结构类型,通常包含字段、属性、方法、属性、构造函数、索引器、操作符等。所有的类都最终继承自System.Object 类,因此是一种引用类型,也就是说,new 一个类的实例时,对象保存了该实例实际数据的引用地址,而对象的值保存在托管堆中。

2.2 什么是结构体

struct (结构体)是一种值类型,用于将一组相关的信息变量组织为一个单一的变量实体 。所有的结构都继承自System.ValueType 类,因此是一种值类型,也就是说,struct 实例分配在线程的堆栈(stack )上,它本身存储了值,而不包含指向该值的指针。所以在使用struct 时,我们可以将其当作int 、char 这样的基本类型类对待。

2.3 相同点与不同点

相同点:语法类似。

不同点:

class是引用类型,继承自System.Object 类;struct 是值类型,继承自System.ValueType 类,因此不具多态性。但是注意,System.ValueType 是个引用类型。 从职能观点来看,class 表现为行为;而struct 常用于存储数据。 class支持继承,可以继承自类和接口;而struct 没有继承性,struct 不能从class 继承,也不能作为class 的基类,但struct 支持接口继承。class 可以声明无参构造函数,可以声明析构函数;而struct 只能声明带参数构造函数,且不能声明析构函数。因此,struct 没有自定义的默认无参构造函数,默认无参构造器只是简单地把所有值初始化为它们的0 等价值 。实例化时,class 要使用new 关键字; 而struct 可以不使用new 关键 字,如果不以new 来实例化struct ,则其所有的字段将处于未分配状态,直到所有字段完成初始化,否则引用未赋值的字段会导致编译错误。

class可以实抽象类(abstract ),可以声明抽象函数;而struct 为抽象,也不能声明抽象函数。

class可以声明protected 成员、virtual 成员、sealed 成员和override 成员;而struct 不可以,但是值得注意的是,struct 可以重载System.Object 的3 个虚方法,Equals() 、ToString() 和GetHashTable() 。

class的对象复制分为浅拷贝和深拷贝(该主题我们在本系列以后的主题中将重点讲述,本文不作详述),必须经过特别的方法来完成复制;而struct 创建的对象复制简单,可以直接以等号连接即可。

class实例由垃圾回收机制来保证内存的回收处理;而struct 变量使用完后立即自动解除内存分配。

作为参数传递时,class 变量是以按址方式传递;而struct 变量是以按值方式传递的。

我们可以简单的理解,class 是一个可以动的机器,有行为,有多态,有继承;而struct 就是个零件箱,组合了不同结构的零件。其实,class 和struct 最本质的区别就在于class 是引用类型,内存分配于托管堆;而struct 是值类型,内存分配于线程的堆栈上。由此差异,导致了上述所有的不同点,所以只有深刻的理解内存分配的相关内容,才能更好的驾驭。本系列将再以后的内容中,将引用类型和值类型做以深入的比较和探讨,敬请关注。当然正如本文标题描述的一样,使用class 基本可以替代struct 的任何场合,class 后来居上。虽然在某些方面struct 有性能方面的优势,但是在面向对象编程里,基本是class 横行的天下。

那么,有人不免会提出,既然class 几乎可以完全替代struct 来实现所有的功能,那么struct 还有存在的必要吗?答案是,至少在以下情况下,鉴于性能上的考虑,我们应该考虑使用struct 来代替class :实现一个主要用于存储数据的结构时,可以考虑struct 。 struct 变量占有堆栈的空间,因此只适用于数据量相对小的场合。结构数组具有更高的效率。 提供某些和非托管代码通信的兼容性。

3 覆写和重载

3.1 覆写

覆写,又称重写,就是在子类中重复定义父类方法,提供不同实现,存在于有继承关系的父子关系。当子类重写父类的虚函数后,父类对象就可以根据赋予它的不同子类指针动态的调用子类的方法。从示例的分析,总结覆写的基本特征包括:

在.NET 中只有以virtual 和abstract 标记的虚方法和抽象方法才能被直接覆写。

覆写以关键字override 标记,强调继承关系中对基类方法的重写。

覆写方法要求具有相同的方法签名,包括:相同的方法名、相同的参数列表和相同的返回值类型。

3.1.1 虚方法

虚方法就是以virtual 关键字修饰并在一个或多个派生类中实现的方法,子类重写的虚方法则以override 关键字标记。虚方法调用,是在运行时确定根据其调用对象的类型来确定调用适当的覆写方法。.NET 默认是非虚方法,如果一个方法被virtual 标记,则不可再被static 、abstrcat 和override 修饰。

3.1.2 抽象方法

抽象方法就是以abstract 关键字修饰的方法,抽象方法可以看作是没有实现体的虚方法,并且必须在派生类中被覆写,如果一个类包括抽象方法,则该类就是一个抽象类。因此,抽象方法其实隐含为虚方法,只是在声明和调用语法上有所不同。abstract 和virtual 一起使用是错误的。

3.2 重载

重载,就是在同一个类中存在多个同名的方法,而这些方法的参数列表和返回值类型不同。值得注意的是,重载的概念并非面向对象编程的范畴,从编译器角度理解,不同的参数列表、不同的返回值类型,就意味着不同的方法名。也就是说,方法的地址,在编译期就已经确定,是这一种静态绑定。从示例中,我们总结重载的基本特征包括:

重载存在于同一个类中。重载方法要求具有相同的方法名,不同的参数列表,返回值类型可以相同也可以不同。.NET引入泛型技术,使得相同的参数列表、相同的返回值类型的情况也可以构成重载。

abstract public class Graph//定义一个图形类

{

public virtual double Area(double length)//定义虚方法

{

return length;

}

public double Area(double length, double width)//参数列表不同

{

return length * width;

}

public double Area(string type, double length, double width)//参数类型不同

{

return length * width;

}

public double Area(double length, double width, double height)//参数的个数不同

{

return length * width * height;

}

public abstract double area();//定义的抽象方法

}

public class triangle : Graph//定义一个三角形类

{

public override double area()//覆写基类抽象方法

{

throw new NotImplementedException();

}

public override double Area(double length)//覆写基类抽象方法

{

return base.Area(length);

}

}

3.3 覆写和重载比较

如表1所示。

4 小结

本文针对程序员在掌握C#语言的过程中,容易混淆的地方按不同点、相同点、使用场景进行区别,认识其优劣得失,帮助读者提高软件开发效率,养成学习开发语言的良好习惯。

参考文献:

[1] 吴平贵.VC#.NET数据库应用程序设计[M].大连:大连理工大学版社,2009.

[2] 吴平贵.VC#.NET程序设计实训指导[M].大连:大连理工大学版社,2010.

[3] Watson K,Nagel C.C#入门经典[M].4版.北京:清华大学出版社,2008.

注:本文中所涉及到的图表、注解、公式等内容请以PDF格式阅读原文

上一篇:AutoCAD命令的实用小技巧 下一篇:分布式部门主页内容集群管理系统的研究与实现