如何在C#中定义一个类

定义类

C#中类的定义

C#使用class关键字来定义类

class MyClass
{
	//class members;
}

定义了一个类后就可以在项目中能访问到该类的位置实例化该类,默认情况下类的声明为内部的,即只有当前代码才能访问它,可使用internal关键字来显式指出这一点,但是没有必要

internal class MyClass
{
	//class members.
}

此外还可以指定类是公共的,可被其他代码访问,为此要使用关键字public

public class MyClass
{
	//class members.
}	

除了这两个修饰符之外还有abstract和sealed修饰符

public abstract class MyClass //只能继承,不能实例化
public sealed class MyClass //不能继承
//这两个关键字是互斥的

还可以在类定义中指定继承

public class MyClass : MyBase
{
	//Class members.
}

如果继承了一个抽象类,就必须实现所继承的所有抽象方法,一个类也只能有一个基类。
同时一个派生类的可访问性不能高于基类的可访问性,也就是说,内部类可以继承于一个公共基类,但公共基类不能继承于一个内部基类。下面代码是合法的

public class MyBase
{
	//Class members.
}
internal class MyClass : MyBase
{
	//Class members.
}

下面代码无法编译

internal class MyBase
{
 //Class members.
}
public class MyClass : MyBase
{
 //Class members.
}

支持某一接口的类必须实现所有的接口成员
类的实例可以调用一个继承自System.Object的方法ToString(),该方法会把对象的类名作为一个字符串返回,同时用该类名的名称空间来限定。

System.Object

所有类都继承于System.Object,所以这些类都可以访问该类中受保护的成员和公共成员,下面列出可供使用的成员有哪些。

方法返回类型虚拟静态说明
Object()N/A构造函数
~Object()N/A析构函数
Equals(object)bool把调用该方法的对象和另一个对象相比,如果他们相等就返回一个true,默认的实现代码会查看其对象参数是否应用了同一个对象,如果想以不同方式来比较对象,则可以重写该方法。
Equals(object,object)bool比较传递给它的两个对象是否相等,比较时使用了上一条命令
ReferenceEquals(object,object)bool比较传递给它的两个变量,看看他们是不是同一个实例的引用
ToString()string返回一个对应于对象实例的字符串。默认情况下这是一个类类型的限定名称,但是可以重写它,给类类型提供合适的实现代码
MemberWiseClonoe()object通过创建一个新对象的实例并复制成员,以复制该对象成员复制不会得到这些成员的新实例,新对象的任何引用类型的成员都将引用和源引用相同的对象,这个方法是受保护的所以只能在类或派生的类中使用。
GetType()System.Type以System.Type的类型返回对象的类型
GetHashCode()int在需要此参数的地方,用作对象的散列函数,它返回一个以压缩形式的标识对象状态的值。

构造函数和析构函数

在C#中定义类时常常不需要定义相关的构造函数和析构函数,因为在编写代码时,如果没有提供他们,编译器会自动提供他们。但如果有必要还是可以提供自己的构造函数和析构函数

class Myclass
{
	public MyClass()
	{
		//Constructor code
	{
}	

接口和抽象类

相似之处:都包含可由派生类继承的成员,都不能直接实例化,但可以声明这些类型的变量,如果这样做,就可以使用多态性把继承这两种类型的对象指定给他们的变量,接着通过这些变量来使用这些类型的成员,但不能直接访问派生对象的其他成员。
区别之处:派生类只能继承自一个基类,即只能继承自一个抽象类(但可以用一个继承链包含多个抽象类)。相反类可以使用任意多个接口,但这不会产生太大的区别,两种情况取得的效果是相似的。

抽象类可以拥有抽象成员(没有代码体,且必须在派生类中实现,否则派生类本身必须也是抽象的)和非抽象成员(它们拥有代码体,也可以是虚拟的,这样就在派生类中重写)。接口成员是公共的(因为他们的目的是在外部使用),但抽象类的成员可以是私有的(只要他们不是抽象的),此外,接口不能包含字段、构造函数、析构函数、静态成员或常量。

抽象类主要用作对象系列的基类,这些对象共享某些主要特性,例如共同的目的和结构。接口则主要用于类,这些类存在根本性的区别,但仍可完成相同的任务。

结构类型

结构是值类型,而类是引用类型,具体区别可由以下代码展示

class MyClass
{
	public int val;
}
struct myStruct
{
	public int val;
}	
class Problem
{
	static void Main(String[] args)
	{	
		MyClass objectA = new MyClass();
		MyClass objectB = ObjectA;
		objectA.val = 10;
		objectB.val = 20;
		myStruct structA = new myStruct();
		myStruct structB = structA;
		structA.val = 30;
		structB.val = 40;
		WriteLine($"objectA.val = {objectA.val}");
		WriteLine($"objectB.val = {objectB.val}");
		WriteLine($"structA.val = {structA.val}");
		WriteLine($"structB.val = {structB.val}");
		ReadKey();
	}
}			

运行程序代码可得

objectA.val = 20
objecrB.val = 20
structA.val = 30
structB.val = 40

类是引用对象,objectA和objectB两个变量就都包含同一个对象的指针。

浅度和深度复制

简单按照成员复制对象可以通过System.Object的MemberwiseClone()方法来完成,这是一个受保护的方法,很容易在对象上定义一个调用该方法的公共方法。这个方法提供的功能叫做浅度复制,因为它并没有考虑到引用类型成员。因此,新对象中的引用成员就会指向源对象中相同成员引用的对象。这在许多情况下并不理想,如果要创建成员的新实例(复制值,而不复制引用),此时需要使用深度复制。
可以实现一个ICloneable接口,以标准方式进行深度复制。如果使用这个方法,就必须实现它包含的Clone()方法。

  • 3
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值