面向过程:分析出解决问题所需要的步骤,即简单的处理问题
面向对象: 把构成问题的事物分解成各个对象,简化程序的开发,面向对象内部的实现,写的还是面向过程的代码,它们是一个互补的关系。
三大特点:
① 封装:把客观事物封装成抽象的类;
② 继承:子类可以使用父类的所有功能,并且对这些功能进行扩展,子类也可以定义自己的功能;
③ 多态:同种事物,多种形态,名称相同,行为方式(实现的内容)不同,这种现象就称为多态。例如,老师和学生都需要上课,但老师是授课,而学生是听课。
多态有两种方式:覆盖(子类重新定义父类的方法)和重载(一个类中允许存在多个同名方法,而这些方法的参数不同)
被继承的类叫基类或者叫父类,继承父类的类叫子类或者派生类,子类扩展了父类。
类分为:数据成员(字段)和函数成员(属性、构造函数)--行为
定义一个对象:类名 方法名
字段:访问修饰符+数据类型+名称(首字母小写)
只读字段:readonly,在程序运行过程中,有一次在构造函数里赋值的机会,对象.字段名,
静态字段:①static,和对象无关,和类有关,所有的对象都共同具有的特点;
②—调用它时,用类名.字段名 ;
③在静态构造函数中初始化
常量:
① 当跟对象无关时,就会用到常量;
② 定义一个常量,所有字母都要大写,单词与单词之间用下划线连接
③ 常量--在编译之前就确定值,并且在程序运行过程中不会发生改变
④ 常量的调用方法是:类名.常量名
Const和readonly比较
相同点:都是用来标识常量的,const用来定义静态常量,readonly用来定义动态常量;
不同点:①const在编译前初始化,其值一经确定不能修改,而readonly有一次在构造函数里赋值的机会;
②const与对象无关,调用它用类名.常量名,而readonly与对象有关,调用它用类名.字段名。
属性:对字段进行封装,get set
构造函数:访问修饰符+类名(参数列表)
public Student(string name, int age)
{
// this代表当前这个对象(当前这个对象的name等于你传进来的这个name)
this.name = name;
this.age = age;
}
① 是用来创建对象的,可以做一些初始化的设置(给类的字段、属性赋值);
② 如果没有定义构造函数,编译器也会给一个默认的构造函数(空的即无参数构造函数),当我们提供一个构造函数后,系统提供的就没有了;
③ 可以有多个构造函数(参数列表不一样),它们在一个类中;
④ 构造函数没有返回类型
静态构造函数:static 类名(){},它没有也不能加访问修饰符
用来初始化静态常量
static Student()
{
company = "863";
}
Console.WriteLine("您的公司是{0}", Student.company);
string sc = Student.company;
Console.WriteLine("您的公司是{0}",sc);
形式参数--形参,实际参数--实参
构造函数的重载:有多个构造函数,名称相同,通过参数列表区分
方法(函数):访问修饰符+返回类型+方法名+参数列表
方法是用来定义对象的行为;
调用方法:对象.方法名(参数);
当方法没有参数,没有返回值时,就用void
public void 方法名()
{ Console.WriteLine("再见");
return;//这个方法调用完就跳出了
}
静态方法:static,调用时用类名.方法名
静态类:它所有成员都必须是静态的,没有对象,没有构造函数,不能初始化
方法的重载:在同一个类中,方法的名称相同,方法的签名不同(参数列表不同)
方法的重写:在不同的类中,方法名称相同,参数列表相同,内容不同;
要加一个关键字:virtual 虚方法—允许子类重写
子类重写父类的虚方法:override
调用基类用关键字base;
调用自己用关键字this。
方法的隐藏:用new关键字;
值传递:方法调用的时候,传递的是参数的副本。(当参数是值类型的时候)
引用传递:方法调用的时候,传递的是参数本身。(当参数是引用类型的时候)string类型除外,它传递时相当于值传递
ref:将值传递变为引用传递
out:输出参数,
运算符重载:operator
public static Box operator +(Box b1,Box b2)
{
Box box = new Box();
box.a = b1.a + b2.a;
box.b = b1.b + b2.b;
box.c = b1.c + b2.c;
return box;
}
索引器:对象后面加[],里面填索引号
ShoppingCar car = new ShoppingCar();
Goods g = car[0];
http://www.cnblogs.com/joeylee/p/3631246.html
继承:简化类的设计;
现实世界遗传关系的直接模拟,表示类之间的内在联系以及实现属性和操作共享;
C#中一个类只能继承一个类(没有明确写的话默认继承object类)
继承中构造函数的执行顺序,由父类开始,沿着继承链向下执行
实例化子类对象的时候构造函数是顺着继承链先往上找,然后从父类开始,每个父类的构造函数都会被继承一遍
c#类的初始化顺序
子类的静态成员变量,子类的普通成员,父类的静态成员,父类的普通成员
首次访问:(在此没有显示的写出类中的构造方法)
顺序:子类的静态字段==》子类静态构造==》子类非静态字段==》父类的静态字段==》父类的静态构造==》父类的非静态字段 ==》父类的构造函数==》子类的构造函数
非首次访问:顺序是一样的,只不过少了中间静态字段和构造的过程
对于静态变量与静态构造函数而言, 无论对一个类创建多少个实例,它的静态成员都只有一个副本。 也就是说,静态变量与静态构造函数只初始化一次(在类第一次实例化时)
基类(父类):被继承的类;调用基类用关键字base;
扩充类(子类):去继承的类;调用自己用关键字this。
class Program
{
static void Main(string[] args)
{
Father f=new Son();
Console.WriteLine(f.age); //这里输出的是父类的年龄?还是子类的年龄? 答案是父亲的年龄 70 ,因为这里的f是个父类类型,所以是调用父类的属性
Son s = f as Son;
Console.WriteLine(s.age); //这里输出的父类的年龄?还是子类的年龄? 答案是子类的年龄 30
Console.ReadKey();
}
public class Father
{
public int age = 70; //第4执行
public static string name = "父亲"; //第3执行
}
public class Son : Father
{
public int age = 30; //第2执行
public static string name = "儿子"; //第1执行
}
}
方法的重载:在同一个类中,方法的名称相同,方法的签名不同(参数列表不同)
方法的重写:在不同的类中,方法名称相同,参数列表相同,内容不同;
要加一个关键字:virtual 虚方法—父类的方法允许子类做一些修改,ToString是一个虚方法
子类重写父类的虚方法:override
父类变量指向子类的实例,但是我们直接调用父类变量下的属性,会输出子类的属性?还是父类的属性?答案是父类的属性.
那如果再继续调用方法的话,是调用父类的方法?还是子类的方法?答案是,如果是虚方法,子类有重写,就调用子类的,子类没有重写,就调用父类的.
总结:
1:当用父类的变量调用属性的时候,取决于声明的类型(“=”左边是什么类型),而不是后面实例化的类型。例如 输出 f.age 就是输出父类的属性 ,而不是子类的属性
2:当子类和父类的方法完全相同时,调用的时候取决于声明的类型(“=”左边),而不是后面实例化的类型。
也就是子类没有重写的时候. f.sayhi 就是调用的父类的sayhi ,而不是子类的sayhi
3 如果子类有重写(override)父类的方法,那么 父类变量调用方法的时候,就变成使用 子类的方法.
也就是子类有override的时候,f.sayhi 就是调用子类的sayhi
4:如果想在子类里面访问父类的属性或者是方法,使用 base 关键字
方法的隐藏:在不同的类中,方法名称相同,参数列表相同,内容不同;用new关键字;
C#中new和override的区别:
①当父类里面有 virtual 方法的时候,子类可以使用 override 进行重写. 那么 f.sayhi 就变成调用子类的sayhi
②不论父类的方法有没有virtual,子类都可以在同名的方法上加一个new表示这是子类自己的方法,那么父类的方法就会被隐藏起来, f.sayhi 就会变成 调用父类的sayhi,因为子类并没有override. 如果这个时候,把new去掉,效果也是一样的,f.sayhi 也是调用父类的sayhi, 判断是否调用子类的方法,就看子类是否有override重写.
在C#中,override和new都会覆盖父类中的方法。那它们两者之前有什么区别呢? ①override是指“覆盖”,是指子类覆盖了父类的方法。子类的对象无法再访问父类中的
②new是指“隐藏”,是指子类隐藏了父类的方法,当然,通过一定的转换,可以在子类的对象中访问父类的方法。
partial类:当一个文件太大时,把它分成两个文件,每个文件都可以获取另一个文件的内容。比如我在1.cs文件定义了一个Student类,在2.cs文件里定义了一个public partial class Student类,那么写在partial类里面的字段,1.cs同样可以获取
抽象类abstract:
①专门做基类(它肯定有子类),让别人来继承,不能实例化对象;
②抽象类里有抽象方法(不一定所有方法都是抽象的),抽象方法(没有方法体)必须在子类中实现
③虚方法子类不一定重写,但抽象类中子类一定要override重写
密封类:sealed,不允许被继承,不可能有子类
接口:Interface
定义接口public interface IName{}
①只有声明部分,没有实现部分,接口里面的方法是不需要访问修饰符的,也不用实现;
② 一个类只能继承一个类,但可以继承多个接口(接口和接口之间用逗号隔开)
③ 接口中包含事件,索引器,方法,属性, 但不能定义字段、构造函数、常量、委托;
④ 类和结构可以继承多个接口,接口自身也可以继承多个接口。
接口和抽象类的区别:
相同点:都不能实例化,都包含未实现的方法,其子类必须实现所有未实现的方法;
不同点:
① 抽象类作为有意义的实例的基类,在业务逻辑中起到基础的作用;而接口是作为模块与模块间,系统与系统之间的交互协议;
② 二者声明的关键字不同,接口的关键字为interface,抽象类的关键字为object;
③ 继承方式不同:子类可以实现多个接口的继承,而只能继承一个抽象类;
④ 方法声明的使用不同:接口中直接给出了方法头,方法在被使用时可以直接实现方法;抽象类中使用abstract声明方法头,方法被使用时需要使用override关键字实现方法。
委托:delegate把方法作为参数传递给另一个方法
访问修饰符 delegate void 委托名(参数列表)参数列表可为空
Main方法、Winform控件也是一个委托
事件:event用来封装委托
事件和委托区别:
委托是一个类,它定义了方法的类型,可以把方法作为另一个方法的参数进行传递,声明委托的关键字为delegate,事件是一种特殊的委托,是类和对象对外发出的消息,声明某行为或某处理条件已成立,即类和对象在发生其关注的事情时用来提供通知的一种方式。
结构体:值类型,而类是引用类型
访问修饰符(5种):
Public(公有的)
Private(私有的,只有类内部可以访问,子类是可以继承的,但不可以访问)
Protected(受保护的,只有类自己和子类才可以访问)
Internal(应用程序集(一个一个的项目), 应用程序集内部可以访问)
修饰类的只能用public或者是internal
Protected Internal
String 和StringBuilder的区别:
二者的功能相似,他们最大的不同在于当生成一个新的string时,string会重新开辟一个新的内存空间,而StringBuilder则在原来的内存中进行修改;
所以,当面临需要多次修改的情况时,用StringBuilder比较合适。
Array ArrayList HashTable的区别
Array:存储类型统一,长度固定,在一开始声明的时候,长度就固定了,堆内存为之分配相对应的内存空间;静态,不灵活;
ArrayList:解决的Array的缺点,它的长度是动态变化的,随着add对象的增加,它的数量(count)逐一增加,它的容量(capacity)成倍(2是指数倍),同时它的存储对象是object类型,即对存储类型没有任何限制,但是它的查询效率比较低;
HashTable:解决了ArrayList的缺点,它的存储对象也是object类型,它可以自定义对象的索引,加速了数据的索引效率。
Ref和out区别:
相同点:ref和out都是按地址进行传递的,使用后都将改变原来参数的值;
不同点:①ref把参数的数值传进函数是会将其原有的数值改变;而out则是直接清空参数的数值;②运行时的处理方式不同,传递到ref参数的参数必须最先初始化,而out参数在传递之前不需要显示初始化。
转载于:https://www.cnblogs.com/wanghuixia/p/9533618.html