观看siki学院的总结
**
类的定义
**
类中的数据和函数称为类的成员
数据成员
函数成员
数据成员:
数据成员是包含类的数据–字段,常量和事件的成员。
函数成员:
函数成员提供了操作类中数据的某些功能。(方法,属性,构造方法和终结器(析构方法),运算符,和索引器)
**
类的字段和方法
**
字段的声明
访问修饰符 类型 字段名称;
**
方法的声明
**
访问修饰符 返回值类型 方法名称(参数){
//方法体
}
class Customer{
public string name;
public string address;
public int age;
public string buyTime;
public void Show(){
Console.WriteLine(“名字:”+name);
Console.WriteLine(“年龄:”+age);
Console.WriteLine(“地址:”+address);
Console.WriteLine(“购买时间:”+buyTime);
}
}
使用我们自定义的类声明的变量也叫做对象,这个过程也叫做实例化。
ClassName myClass = new ClassName();
其中ClassName是我们定义的类的名字,myClass是我们声明的变量(对象)的名字,后面的new是一个关键字,使用new 加上类型名()表示对该对象进行构造,如果不进行构造的话,这个对象是无法使用的。
**
构造函数
**
我们构造对象的时候,对象的初始化过程是自动完成的,但是在初始化对象的过程中有的时候需要做一些额外的工作,例如需要初始化对象存储的数据,构造函数就是用于初始化数据的函数。
声明基本的构造函数的语法就是声明一个和所在类同名的方法,但是该方法没有返回类型。
public class MyClass{
public MyClass(){
这个构造函数的函数体
}
}
当我们使用new关键字创建类的时候,就会调用构造方法。
我们一般会使用构造方法进行初始化数据的一些操作。
构造函数可以进行重载,跟普通函数重载是一样的规则
注意:
当我们不写,任何构造函数的时候,编译器会提供给我们一个默认的 无参的构造函数,但是如果我们定义了一个或者多个构造函数,编译器就不会再提供默认的构造函数
**
属性
**
属性的定义结构
public int MyIntProp{
get{
// get code
}
set{
//set code
}
}
属性包含两个set和get块,取属性的值时调用get块,给属性设置值调用set块,在set
块通过value访问我们设置的值。
通常我们把字段设置为私有,可以通过设置属性来访问字段(习惯上属性值大写)
private int age;
public int Age{
set{
if(value<0)return;
age = value;
}
get{
return age;
}
}
属性值可以只写get块或只写set块
可以在属性的块中设置访问修饰符
public string name{
get{
return name;
}
private set{
name = value;
}
}
public int Age{get;set;} 系统会自动创建age的属性
**
匿名类型
**
var var1 = 34;
当使用var声明匿名类型,初始化类型就确定下来了,后面也不可以修改。
推和栈的:程序运行的内存区域
类型被分为两种:值类型(整数,bool struct char 小数)和引用类型(string 数组 自定义的类,内置的类)。
值类型只需要一段单独的内存,用于存储实际的数据,(单独定义的时候放在栈中)
引用类型需要两段内存
第一段存储实际的数据,它总是位于堆中
第二段是一个引用,指向数据在堆中的存放位置
如果数组是一个值类型的数组,那么数组中直接存储值,如果是一个引用类型的数组(数组中存储的是引用类型),那么数组中存储的是引用(内存地址)
**
继承
**
实现继承
表示一个类型派生于一个基类型,它拥有该基类型的所有成员字段和函数。
C#不支持多重实现继承。
如果要声明派生自另一个类的一个类,就可以使用下面的语法:
class MyDerivedClass : MyBaseclass
{
// functions and data members here
}
如果类(或 结构)也 派生 自接 口,则用逗号分隔列表中的基类和接 口:
public class MyDerivedClass: MyBaseClass , IInterface1 , IInterface2
{
// etc.
}
继承:父类里面的所有数据成员和函数成员都会继承到子类里面
父类声明的对象,可以使用子类去构造,子类声明的对象,父类不能去构造
Enemy enemy;
enemy = new Boss(); Enemy——父类 Boss——子类
enemy虽然使用父类声明,但可以使用子类去构造,本质上是一个子类类型,可以强制类型转换转换为子类
Boss boss = (boss)enemy
一个对象是什么类型,主要看它通过什么构造,如果一个对象被父类构造,只有父类的字段和方法,不能强制转换为子类
**
虚方法
**
把一个基类函数声明为virtual,就可以在任何派生类中重写该函数:
class MyBaseClass{
public virtual string VirtualMethod(){
return "Method is called in base class";
}
}
在派生类中重写另外一个函数时,要使用override关键字显示声明
class MyDerivedClass:MyBaseClass{
public override string VirtualMethod(){
return “Method is called in derivedclass.”;
}
}
我们在子类里面重写虚函数之后,不管在哪里调用都是调用重写之后的方法(对象由子类构造)
对象由父类构造时,调用的虚函数就是父类的虚函数
**
隐藏方法
**
如果签名相同的方法在基类和派生类中都进行了声明,但是该方法没有分别声明为virtual和override,派生类就会隐藏基类方法。(要使用new关键字进行声明)
基类
class MyBaseClass{
public int MyMethod(){
}
}
派生类(在派生类中把基类同名的方法隐藏掉了)
class MyDerivedClass :MyBaseClass{
public new void MyMethod() {
}
}
当子类里面有一个签名和父类相同的方法的时候,就会把父类的方法隐藏(父类的方法还存在)
父类声明的对象调用的是父类的方法,子类声明的对象调用的是子类的方法
Boss boss = new Boss();
boss.move();
Enemy boss = new Enemy();
Boss.move();
Enemy——父类 Boss——子类
**
this和base关键字
**
this可以访问当前类中定义的字段,属性和方法,有没有this都可以访问,有this可以让IDE-VS编译器给出提示,另外当方法的参数跟字段重名的时候,使用this可以表明访问的是类中的字段,base可以调用父类中的公有方法和字段,有没有base都可以访问,但是加上base.IED工具会给出提示,把所有可以调用的字段和方法罗列出来方便选择
**
抽象类
**
C#允许把类和函数声明为 abstract。 抽象类不能实例化,抽象类可以包含普通函数和抽象函数,抽象函数就是只有函数定义没有函数体。显然,抽象函数本身也是虚拟的Virtual(只有函数定义,没有函数体实现)。
类是一个模板,那么抽象类就是一个不完整的模板,我们不能使用不完整的模板去构造对象。
abstract class Building{
public abstract decimal CalculateHeatingCost();
}
可以通过抽象类去声明对象,但是不可以去构造
密封类和密封方法
C#允许把类和方法声明为 sealed。 对于类 ,这表示不能继承该类;对于方法表示不能重写该方法。
sealed FinalClass
{
// etc
}
**
派生类的构造函数
**
1,在子类中调用父类的默认构造函数(无参)(会先调用父类的,然后是子类的)
public class MyDerivedClass{
public MyDerivedClass():base(){
//do something
}
}
在这里 :base()可以直接不写,因为默认会调用父类中的默认构造函数
2,调用有参数的构造函数
public class MyDerivedClass{
public MyDerivedClass(string name):base(name){
//do something
}
}