定义类、System.Object对象、构造函数与析构函数、抽象类与静态类
一、类定义
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
{
}
Type.GetType()静态方法
- typeof运算符
在.Net中,下面的方法能够实现与System.Object的GetType()方法相同的效果:
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对象、构造函数与析构函数、抽象类与静态类的更多相关文章
- .NET基础 (11)类型的基类System.Object
类型的基类System.Object1 是否存在不继承自System.Object类型的类2 在System.Object中定义的三个比较方法有何异同3 如何重写GetHashCode方法 类型的基类 ...
- C++学习笔记(7)----类的数组中构造函数和析构函数的调用顺序
C++类的数组中构造函数和析构函数的调用顺序(2) 对于如下的代码: #include<iostream> using namespace std; class CBase { priva ...
- C++类中函数(构造函数、析构函数、拷贝构造函数、赋值构造函数)
[1]为什么空类可以创建对象呢? 示例代码如下: #include <iostream> using namespace std; class Empty { }; void main() ...
- C++类继承中的构造函数和析构函数 调用顺序
思想: 在C++的类继承中,构造函数不能被继承(C11中可以被继承,但仅仅是写起来方便,不是真正的继承) 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时, ...
- (C++)C++类继承中的构造函数和析构函数
思想: 在C++的类继承中, 建立对象时,首先调用基类的构造函数,然后在调用下一个派生类的构造函数,依次类推: 析构对象时,其顺序正好与构造相反: 例子: #include <iostream& ...
- 《C++ Primer Plus》10.3 类的构造函数和析构函数 学习笔记
10.3.1 声明和定义构造函数构造函数原型:// constructor prototype with some default argumentsStock(const string &c ...
- c++, 派生类的构造函数和析构函数 , [ 以及operator=不能被继承 or Not的探讨]
说明:文章中关于operator=实现的示例,从语法上是对的,但逻辑和习惯上都是错误的. 参见另一篇专门探究operator=的文章:<c++,operator=>http://www.c ...
- C++将类的构造函数、析构函数声明为private或者protected的用途
如果将构造函数.析构函数声明为private或者protected,表示不能从类的外部正常调用构造和析构函数了. 这种用法的通常使用的场景如下: 1.如果不想让外面的用户直接构造一个类A的对象,而希望 ...
- C#定义类成员
1.成员定义 public--成员可以由任何代码访问. private--成员只能由类中的代码访问(如果没有使用任何关键字,就默认使用这个关键字). internal--成员只能由定义它的程序集(项目 ...
随机推荐
- SQL Server中的小技巧(重复、替换、截取、去空格、去小数点后的位数)
PS:随笔写的在SQL Server中要用到的 (重复.替换.截取.去空格.去小数点后的位数) /*---------------------------重复--------------------- ...
- DataGridView 绑定数据方法
DataGridView控件用于显示来自多种外部数据源中的数据,用户可以在此控件添加行和列,并可以填充数据. 如要让DataGridView显示数据库中的数据,只需要将此控件绑定到挑用数据库的数据 ...
- vscode下eslint代码规范
直接上规范吧: // 将设置放入此文件中以覆盖默认设置 { "editor.fontSize": 17, "editor.tabSize": 2, " ...
- Cheatsheet: 2018 03.01 ~ 2018 03.31
Docker A Developer's Guide to Docker: A Gentle Introduction The Advantages of Using Kubernetes and D ...
- java虚拟机的内存机制
我们都知道,java程序的跨平台性离不开java虚拟机,虚拟机隔绝了底层操作系统,使得java程序可以直接运行在虚拟机之上.所以,对java的学习,离不开对java虚拟机的学习与了解.下面简单整理下j ...
- 判定 java 对象死亡的过程
- distinct 用法
参考 1.作用于单列 2.作用于多列 3.COUNT统计 4.distinct必须放在开头 5.其他 在表中,可能会包含重复值.这并不成问题,不过,有时您也许希望仅仅列出不同(distinct)的值. ...
- 【零基础学习FreeRTOS嵌入式系统】之一:FreeRTOS环境搭建
[零基础学习FreeRTOS嵌入式系统]之一:FreeRTOS环境搭建 一:FreeRTOS系统下载 在官网上https://www.freertos.org/,找到下载入口. 或直接进入下载地址ht ...
- sql: Oracle 11g create table, function,trigger, sequence
--书藉位置Place目录 drop table BookPlaceList; create table BookPlaceList ( BookPlaceID INT PRIMARY KEY, -- ...
- [HNOI2006]最短母串问题
题目大意:给定一个字符串集,求一个最短字串,使得该集合内的串都是该串的一个子串 算法:AC自动机+最短路+状压DP 注意空间限制 #include"cstdio" #include ...