在上一篇文章中,介绍了类如何封装程序中的对象.而实际中,出了类可以封装对象外,结构和枚举也可以封装一些对象,本文将着重介绍结构和枚举这两个知识点的相关应用.
一. 结构(Structure)
什么是结构(Structure)?在C#里,Struct是一种值类型,通常用来封装小型相关变量组,和类有很大的相似度.同类一样,它不但可以包含不同数据类型数据。还可以包含复合类型(数组,结构,DateTime等等)除了以名字/值方式出现还可以有属性和方法,所以说结构是一种强大的复合型数据。
1. 使用类封装对象的属性
以图书来作为示例来分析,图书包括图书编号,图书名称,图书作者以及出售价格等.我们平时所通常都是使用类来封装这些信息,如下:
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 图书对象
3
/// </summary>
4
public class Books
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6
public int bookId;
7
public string bookName;
8
public string bookAuthor;
9
public double bookPrice;
10
}
2. 使用结构封装对象的属性
其实出了使用类来封装,我们还可以使用结构来封装,实现如下:
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 使用结构封装图书信息
3
/// </summary>
4
public struct Book
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6
public int bookId;
7
public string bookName;
8
public string bookAuthor;
9
public double bookPrice;
10
}
3. 结构可以定义构造方法
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 使用结构封装图书信息
3
/// </summary>
4
public struct Book
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**//// <summary>
7
/// 可定义构造方法
8
/// </summary>
9
public Book()
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
11
//![](https://www.cnblogs.com/Images/dot.gif)
![](https://www.cnblogs.com/Images/dot.gif)
12
}
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
public int bookId;
15
public string bookName;
16
public string bookAuthor;
17
public double bookPrice;
18
}
4. 可以使用new进行初始化
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 使用结构封装图书信息
3
/// </summary>
4
public struct Book
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
/**////// <summary>
7
///// 可定义构造方法
8
///// </summary>
9
//public Book()
10
//{
11
// //这里需要注意,当结构中已有带参数的构造方法时,则不能定义无参数的构造方法
12
//}
13![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
14
public Book(int id, string name, string author, double price)
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
bookId = id;
17
bookName = name;
18
bookAuthor = author;
19
bookPrice = price;
20
}
21
public int bookId;
22
public string bookName;
23
public string bookAuthor;
24
public double bookPrice;
25
}
5. 结构可以实现接口
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 接口
3
/// </summary>
4
public interface IBook
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6
DataSet QueryAll();
7
}
8![](https://www.cnblogs.com/Images/OutliningIndicators/None.gif)
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
10
/// 结构实现接口
11
/// </summary>
12
public struct BookComponent : IBook
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
14
public DataSet QueryAll()
15![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
16
return null;
17
}
18
}
6. 类和结构的区别
从上面可以看出,无论是使用类还是结构,都可以用来封装对象的属性.当然出了相同点外,两者之间还是有很大的不同,大体如下:
类型:类是引用类型,结构是值类型.
继承:类可继承,结构不能继承.结构不能继承其他的结构和类,或是被用作其他结构或类的基类.
构造方法与析够函数:结构可以定义构造方法,但不能定义析够函数.类既可以定义构造方法,也可定义析够函数.
对象创建:可以使用new进行初始化,或进行手工初始化.类和结构都可以.
结构与接口:结构可以实现一个或多个接口. 如上:public struct BookComponent:IBook{ //....}.
多态: 结构与接口之间是支持多态的.如上面的结构实现接口为例,多态:IBook book = new BookComponent();
二. 枚举(Enumeration)
什么是枚举(Enumeration)?枚举可以理解为通过预定义列出所有值的标识符来定义一个有序集合,这些值的次序和枚举说明中的标识符的次序一致的. 通常用于定义一些不变的序列,如一年四个季节,一礼拜为七天等等. 可以通过enum来定义(这里主要是针对C#语言的实现,其实在JAVA语言里也是通过enum来定义).
1. 枚举的定义形式
修饰符 enum 枚举名
{
标识符1,
标识符2,
..........,
标识符n
}
如下则为一个完整的枚举定义:
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
2
/// 技术方向
3
/// </summary>
4
public enum TechnologyDirection
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
6
CPlusPlus程序员,
7
Java程序员,
8
DotNet程序员,
9
架构设计师,
10
开发组长,
11
需求分析师
12
}
2. 另类枚举定义(可以初始化值)
1
==============以下为第一种定义方法==============
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
3
/// 季节
4
/// </summary>
5
public enum Season
6![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
7
SPRING, //春天
8
SUMMER, //夏天
9
AUTUMN, //秋天
10
WINTER //冬天
11
}
12
==============以下为第二种定义方法==============
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
/**//// <summary>
14
/// 季节
15
/// </summary>
16
public enum SeasonTwo
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
18
SPRING = 0, //春天
19
SUMMER = 1, //夏天
20
AUTUMN = 2, //秋天
21
WINTER = 3 //冬天
22
}
23
=================TEST===================
24
class Program
25![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
26
static void Main(string[] args)
27![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
28
//以上两种定义方法效果都一样
29
Console.WriteLine(Season.AUTUMN);
30
Console.WriteLine(SeasonTwo.AUTUMN);
31
//运行结果都为:AUTUMN
32
}
33
}
如果不初始化值则从0开始,实际上面两种定义方式定义得到的都是一个效果.
3. 对象的形式实现
何为对象的形式实现呢? 其实这个很简单,也就是将需要枚举的标识定义在对象里,通过对象的特性将其封装.详细如下代码:
1
public class SeasonOne
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
3
public static readonly SeasonOne SPRING = new SeasonOne("春天");
4
public static readonly SeasonOne SUMMER = new SeasonOne("夏天");
5
public static readonly SeasonOne AUTUMN = new SeasonOne("秋天");
6
public static readonly SeasonOne WINTER = new SeasonOne("冬天");
7![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
8
public SeasonOne(string name)
9![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
10
this.name = name;
11
}
12![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
13
//成员
14
private string name;
15
public string Name
16![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
get
{ return name; }
18![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
set
{ name = value; }
19
}
20
}
以上的形式实现很简单, 不过好象已经偏离了"枚举(enum)",因为实现已经由枚举转向为了类(class)对象来实现了.定义一成员属性,通过构造方法初始化,在类里定义需要枚举的只读成员,通常不建议使用此方式来实现. 我们可以这样来测试:
1
class Program
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](https://www.cnblogs.com/Images/OutliningIndicators/ContractedBlock.gif)
{
3
static void Main(string[] args)
4![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
5
Console.WriteLine(SeasonOne.AUTUMN.Name);
6
//运行结果:秋天
7
}
8
}
4. Java中的枚举
在与C#语言一样流行的JAVA中,枚举还存在着另类故事,作为一个面向对象的开发者或是既将成为面向对象的开发者的你,我想了解下另类语言的某些特性是有必要的.在JAVA中,枚举除了上面所介绍的相关功能外,还有其他的一些功能,下面将简单的介绍下这些功能的应用.
枚举里定义抽象方法,标识符实现抽象方法
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
enum Operator
{
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
ADD
{
3![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public double calculate(double a,double b)
{
4
return a+b;
5
}
6
},
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
SUBSTRACT
{
8![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public double calculate(double a,double b)
{
9
return a-b;
10
}
11
},
12![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
MULTIPLY
{
13![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public double calculate(double a,double b)
{
14
return a*b;
15
}
16
},
17![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
DIVIDE
{
18![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public double calculate(double a,double b)
{
19
return a/b;
20
}
21
};
22
public abstract double calculate(double a,double b);
23
}
枚举里定义属性字段和构造方法
1![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
enum Course
{
2
COREJAVA("zhangsan"), //zhangsan学CoreJava
3
WEB("lisi"), //lisi学Web
4
EJB ("wangwu"); //wangwu学EJB
5![](https://www.cnblogs.com/Images/OutliningIndicators/InBlock.gif)
6
String name;
7![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Course(String name)
{
8
this.name=name;
9
}
10![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getName()
{
11
return this.name;
12
}
13
}
属性字段,构造方法及抽象方法并存
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
enum Course
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
COREJAVA("zhangsan")
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void study()
{
System.out.println("Study Corejava");
}
},
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
WEB("lisi")
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void study()
{
System.out.println("Study Web");
}
},
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
EJB ("wangwu")
{
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public void study()
{
System.out.println("Study EJB");
}
};
String teachName;
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
Course(String name)
{
this.teachName=name;
}
![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
public String getName()
{
return this.teachName;
}
public abstract void study();
}
三. .NET Framework中的枚举基类
在.NET Framework中枚举基类(Enum)是一抽象类,位于System命名空间下,继承了ValueType类和IComparable, IFormattable, IConvertible接口,这里以一个简单的文本编辑作为示例介绍下枚举在实际中的应用.
简单文本编辑器示例运行图如下:
![](https://images.cnblogs.com/cnblogs_com/beniao/csharpseven/enum.jpg)
从上图很容易看出,此文本编辑器主要是用于设置字体样式,其实在实现这个简单文本编辑器的时候就是使用的字体样式枚举(FontStyle),FontStyle的源代码定义如下:
1
// 摘要:
2
// 指定应用到文本的字形信息。
3
[Flags]
4
public enum FontStyle
5![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
}{
6
// 摘要:
7
// 普通文本。
8
Regular = 0,
9
//
10
// 摘要:
11
// 加粗文本。
12
Bold = 1,
13
//
14
// 摘要:
15
// 倾斜文本。
16
Italic = 2,
17
//
18
// 摘要:
19
// 带下划线的文本。
20
Underline = 4,
21
//
22
// 摘要:
23
// 中间有直线通过的文本。
24
Strikeout = 8,
25
}
要实现上图示的简单文本编辑器很简单,基本思路就是通过点击上面字体样式设置功能键,设置编辑区域的文本字体样式,这实现很简单.在此,我就直接把代码贴出来,有不清楚之处可从下面我提供的示例代码下载连接下载本文示例代码查看.
1
private void SetStyle(object sender,EventArgs e)
2![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
}{
3
ToolStripButton btn = sender as ToolStripButton;
4
FontStyle fontStyleContent = this.rchTxtContent.SelectionFont.Style;
5
FontStyle BtnFont = ( FontStyle)(Enum.Parse(typeof(FontStyle),btn.Tag.ToString()));
6
if ((fontStyleContent | BtnFont) == fontStyleContent)
7
{
8
fontStyleContent = ~BtnFont & fontStyleContent;
9
}
10
else
11![](https://www.cnblogs.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
{
}{
12
fontStyleContent = fontStyleContent | BtnFont;
13
}
14
this.rchTxtContent.SelectionFont = new Font(this.rchTxtContent.SelectionFont.FontFamily,
15
this.rchTxtContent.SelectionFont.Size,
16
fontStyleContent,
17
this.rchTxtContent.SelectionFont.Unit);
18
}
本文就介绍于此,更多请关注本系列后续文章,本文示例代码下载
注: 原创文章,转载请注明出处: http://beniao.cnblogs.com/ 或 http://www.cnblogs.com/ 作者 : Beniao