一、类定义

class MyClass
{
//类成员
}

1、访问级别

默认访问级别为internal(内部类),也可以是public(公共类)

  • internal(内部类):当前项目中的代码才能访问
  • public(公共类):任何地方都能访问
public class MyClass
{
//类成员
}

2、继承修饰符

  • abstract(抽象类):不能实例化,只能继承。
  • seald(密封类):不能被继承,无派生类。
  • static(静态类):只包含静态成员的类。
public sealed class MyClass
{
//类成员
}

二、类继承

c#中,一个类只能有一个基类,类默认继承自System.Object类。

public class MyBase
{
//基类
}
public class MyDerivedClass : MyBase
{
//派生类
}

一个类可以实现多个接口。当一个类既继承自一个基类,又实现接口时,基类必须紧跟在冒号的后面,之后才是接口。

public class MyDerivedClass : MyBase, IMyInterface
{
//派生类
}

三、System.Object的成员

  • Object():构造函数,初始化 Object 类的新实例。
  • ~Object():析构函数,引用 Finalize()函数,在垃圾回收将某一对象回收前允许该对象尝试释放资源并执行其他清理操作。Finalize()可重写。
  • Equals(Object):静态方法。确定指定的对象是否等于当前对象。可重写。
  • Equals(Object, Object):静态方法。确定指定的对象实例是否被视为相等。
  • GetHashCode():作为默认哈希函数。可重写。
  • GetType():获取当前实例的类型。虚方法,用于在运行时通过查询对象元数据来获取对象的运行时类型。子类无法通过覆写GetType()而篡改类型信息,从而保证了类型安全。
void Main()
{
MyBaseClass myBase = new MyBaseClass();
MyDerivedClass myDerived = new MyDerivedClass();
object o = myDerived;
MyBaseClass b = myDerived;
Console.WriteLine(myBase.GetType());//UserQuery+MyBaseClass
Console.WriteLine(myDerived.GetType());//MyDerivedClass
Console.WriteLine(o.GetType());//MyDerivedClass
Console.WriteLine(b.GetType());//MyDerivedClass
} class MyBaseClass
{ } class MyDerivedClass : MyBaseClass
{
}

    在.Net中,下面的方法能够实现与System.Object的GetType()方法相同的效果:

  1. Type.GetType()静态方法

  2. typeof运算符
Type t = Type.GetType("ConsoleApplication.Person");
Type t = typeof(ConsoleApplication.Person);
  • MemberwiseClone():创建当前 Object 的浅表副本。

对类里的引用对象只克隆地址,其实还是指向同一个对象。所以仅仅能在类或派生的类中使用。

void Main()
{
A a = new A();
A b = a;
b.M = "b";
Console.Write(a.M);//b
Console.Write(b.M);//b
} class A : System.ICloneable
{
public string M = "a";
public object Clone()
{
return (object)this.MemberwiseClone(); ;
}
}
  • ReferenceEquals(Object, Object):确定指定的 Object 实例是否是相同的实例。
  • ToString():返回表示当前对象的字符串。默认返回对象带命名空间的全名。可重写。

假设继承类须要在处理字符串格式化、语言文化方面控制很多其它格式化输出,则须要实现IFormattable接口。
大部分.Net基本类型都实现了IFormattable接口,用于实现更灵活的字符串信息输出。IFormattable接口的定义如下:

public interface IFormattable
{
string ToString(string format, System.IFormatProvider formatProvider);
}

四、构造函数(Construction)与析构函数(Destruction)

c#中,通常不需要定义类的构造函数和析构函数,因为基类System.Object已提供了默认的实现方式。(自动生成一个不带参数的构造函数,为字段初始化为默认值。)

也可以提供自己的构造函数和析构函数,用于初始化对象和清理对象。

class MyClass
{
public MyClass()//默认构造函数。显式定义了默认构造函数,就不会自动生成一个不带参数的构造函数了。
{
}
public MyClass(int a)//带参数的构造函数
{
}
}

1、私有构造函数:

保证类不能实例化。

public sealed class Singleton
{
private static readonly Singleton instance = new Singleton();
private Singleton()
{
}
public static Singleton Instance
{
get { return instance; }
}
}

2、静态构造函数:

对类(而不是对实例)进行一些初始化,在创建类第一个实例或引用任何静态成员之前,将自动调用静态构造函数,并且只执行一次。此函数不可继承。

作用:用于初始化一些静态数据,或用于执行仅需执行一次的特殊操作。

class MyClass
{
static readonly long baseline; static MyClass()//无访问修饰符,无参数,只有一个static标记。
{
baseline=DateTime.Now.Ticks;
}
}

1、无参数构造函数也可与静态函数共存,尽快参数列相同,但一个属于类,一个属于实例,不会冲突。

2、若未写静态构造函数,而类中包含有初始值设定的静态成员,将会自动使用默认的静态构造函数。

3、继承中构造函数的执行序列:

构造函数不继承基类的构造函数,自动调用基类默认构造函数。

1、默认执行序列,默认为base(),即先执行基类的默认构造函数,再执行派生类的构造函数,基类的默认构造函数此时需要显示创建。

void Main()
{ B objB1=new B();//1-4
B objB2=new B("a");//1-5
B objB3=new B("a","b");//1-6
} class A
{
public A()
{
Console.WriteLine("1");
}
public A(string a)
{
Console.WriteLine("2");
} public A(string a, string b)
{
Console.WriteLine("3");
}
} class B : A
{
public B()
{
Console.WriteLine("4");
}
public B(string a)
{
Console.WriteLine("5");
} public B(string a, string b)
{
Console.WriteLine("6");
}
}

2、基类中带参数的构造函数,派生类必须显示调用。

void Main()
{
B objB1 = new B();//2-6-4
//显式使用base调用基类的特定构造函数,则不执行基类的默认构造函数。
} class A
{
public A()
{
Console.WriteLine("1");
}
public A(string a)
{
Console.WriteLine("2");
} public A(string a, string b)
{
Console.WriteLine("3");
}
} class B : A
{
public B() : this("a", "a")
{
Console.WriteLine("4");
}
public B(string a)
{
Console.WriteLine("5");
} public B(string a, string b) : base(a)
{
Console.WriteLine("6");
}
}

4、析构函数

当进行垃圾回收时,就会执行析构函数,以释放资源。在调用这个析构函数后,还将隐式的调用基类的析构函数,包括System.Object中Finalize()函数。

class MyClass
{
~MyClass()
{ }
}

注意:我们不能依赖析构函数释放资源,因为在进行垃圾回收前,资源可能长时间占用,使用using关键字,可再代码尾自动调用对象的Dispose()方法。

void Main()
{
using (MyClass A = new MyClass())
{
//---
}
} class MyClass : IDisposable
{
public void Dispose()
{
//----
}
}

五、接口的定义

interface IMyInterface //接口默认访问级别为internal,也可以是public
{
//接口成员
}

六、抽象类

使用方法

  • 抽象类关键字可用于类、方法、属性、索引器及事件。
  • 抽象类不能实例化。
  • 派生的子类必须包括父类所有抽象成员的实现。
  • 抽象方法和抽象属性只允许在抽象类中。
  • 抽象成员不提供实现。
void Main()
{
A b = new B();
b.X = 10;
b.F();//BF
b.M();//BM //如果B不重写M方法,则b.M()返回AM
B.N();//static
A.N();//static
} abstract class A
{
protected int _x;
public abstract int X//抽象属性
{
get; set;
}
public abstract void F();//抽象方法
public virtual void M()//虚拟方法,可继承
{
Console.Write("AM");
}
public static void N()//静态方法,可继承
{
Console.Write("static");
}
} class B : A
{ public override int X//必须重写属性X
{
get { return _x; }
set { _x = value; }
}
public override void F()//必须重写方法F
{
Console.Write("BF");
}
public override void M()//可以重写方法M
{
Console.Write("BM");
}
}

抽象类和接口的区别

相同点:都包含可以由派生类继承的成员,都不能直接实例化,但都可以声明他们类型的变量。

不同点:

1、接口所有成员都没有代码体,抽象类可以有抽象成员和非抽象成员(可以是虚拟的,以便重写)。

2、接口成员默认是公共的,抽象成员可以是private,protected,internal等。

3、接口只有成员、方法、属性和事件,抽象类还可以有字段、构造函数、析构函数、静态成员或常量。

4、接口用作完成某些相同的任务,抽象类主要用作共享某些主要特性。

七、静态类

例如System.Math类,静态类的所有成员都是静态,默认继承自System.Object,不能从其他类派生,也不能实现接口。

  • 1、静态类可以有静态构造函数。
  • 2、静态类是密封的,不可被继承。
  • 3、静态类最大的特点就是共享。
static class MyClass
{
public static MyClass()
{
//--
}
}

定义类、System.Object对象、构造函数与析构函数、抽象类与静态类的更多相关文章

  1. .NET基础 (11)类型的基类System.Object

    类型的基类System.Object1 是否存在不继承自System.Object类型的类2 在System.Object中定义的三个比较方法有何异同3 如何重写GetHashCode方法 类型的基类 ...

  2. C++学习笔记(7)----类的数组中构造函数和析构函数的调用顺序

    C++类的数组中构造函数和析构函数的调用顺序(2) 对于如下的代码: #include<iostream> using namespace std; class CBase { priva ...

  3. C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)

    [1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...

  4. C++类继承中的构造函数和析构函数 调用顺序

    思想: 在C++的类继承中,构造函数不能被继承(C11中可以被继承,但仅仅是写起来方便,不是真正的继承) 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时, ...

  5. (C++)C++类继承中的构造函数和析构函数

    思想: 在C++的类继承中, 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时,其顺序正好与构造相反: 例子: #include <iostream& ...

  6. 《C++ Primer Plus》10.3 类的构造函数和析构函数 学习笔记

    10.3.1 声明和定义构造函数构造函数原型:// constructor prototype with some default argumentsStock(const string &c ...

  7. c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]

    说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...

  8. C++将类的构造函数、析构函数声明为private或者protected的用途

    如果将构造函数.析构函数声明为private或者protected,表示不能从类的外部正常调用构造和析构函数了. 这种用法的通常使用的场景如下: 1.如果不想让外面的用户直接构造一个类A的对象,而希望 ...

  9. C#定义类成员

    1.成员定义 public--成员可以由任何代码访问. private--成员只能由类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字). internal--成员只能由定义它的程序集(项目 ...

随机推荐

  1. 深入redis内部--实现字符串

    redis字符串的定义和实现在Ssd.h和Ssd.c中. 1.定义 typedef char *sds; //本质是字符char的指针 2.字符串的操作 sds sdsnew(const char * ...

  2. i.mx android6 输入子系统分析(未完)

    参考:http://blog.csdn.net/u010312937/article/details/53285286 https://www.jianshu.com/p/7fca94b330ea   ...

  3. [转]IIS的各种身份验证详细测试

    本文转自:http://www.cnblogs.com/chnking/archive/2007/11/20/965553.html#_Toc183326163 一.    IIS的身份验证概述 1. ...

  4. SQLite数据类型(学习必备)

    最近在学习android端的数据库,以下知识点作为备用- 一.存储种类和数据类型: SQLite将数据值的存储划分为以下几种存储类型:     NULL: 表示该值为NULL值.     INTEGE ...

  5. 使用NPOI,完成数据的导入导出

    解释下流程,第一步:将数据库表中的数据导出到excel表                          第二步:将excel表中的数据再插入到数据库表中(当然没有做重复性校验,测试而已)注:表结构 ...

  6. ssm集成redis

    身在一个传统的IT公司,接触的新技术比较少,打算年后跳槽,所以抽空学了一下redis. 简单的redis测试,咱们这边就不讲了,现在主要讲讲ssm集成redis的过程,因为现在项目用的就是ssm的框架 ...

  7. java web工程web.xml介绍

    转载自:http://blog.csdn.net/believejava/article/details/43229361 Web.xml详解: 1.web.xml加载过程(步骤) 首先简单讲一下,w ...

  8. mysql 中优化数据类型的三个原则

    数据类型越小越好 在业务够用的情况下,尽可能选取小的数据类型.不仅占用空间小,而且执行查询等操作时性能好. 越简单越好 对于简单的类型,在处理时会占用更少的 CPU 周期. 例如,整数就比字符类型简单 ...

  9. 如何迎接新的 .NET 时代

    看完.NET 基金会. Roslyn 编译器 ,应该已经能慢慢了解,现在所谓的“.NET 开源”.“.NET Open Source”并不是完全把现有的 .NET Framework 整个打开(虽然这 ...

  10. Oracle数据库基本操作 (六) —— 数据的导出与导入

    一.cmd 下登录oracle数据库下的指定用户 方式一:命令行明文连接登录 打开cmd,输入:sqlplus/nolog 输入:conn username/passworld@数据库实例名 方式二: ...