自己用的C#基础学习笔记(二)——C#面向对象(1)
来源:互联网 发布:源码怎么用 编辑:程序博客网 时间:2024/05/22 17:41
C#面向对象
1 第八天
1.1 对象和类
相同属性和方法的对象 的特性进行封装,抽象出类的概念。
类创建出来,如果不做调用,不占用内存,只有创建对象的时候才会开辟空间。
1.1.1 类的语法
[public ] class 类名{
字段;
属性;
方法;
}
1.1.2 字段
字段一般下划线开头
让其他类使用该字段必须将字段共有,即加上public
不写默认不是public
私有的字段只能本类内使用
1.1.3 属性
对字段的保护,避免非法值的输入。属性都有get{}和set{}方法(注意没有小括号),可以通过这两个方法来控制字段的输入和输出内容
属性名可以和公共的枚举名同名。
属性名应该根据保护的字段来取,让人一看能知道该属性属于哪个字段的。
public string Name{
get{//该方法在输出的时候会自动调用该方法。
return name(字段名);
}
set{//在赋值的时候会调用set方法
name(字段名)= value;//value为赋的值,处理时一定注意不要判断字段,而是判断value,value的数据类型是属性定义的数据类型。
}
}
有了属性之后,可以将字段私有,通过公有的属性来进行赋值获取,此时属性可以完全当做字段来使用,举例:
Person p = new Person(); p.Name=”1231”;
1.2 构造函数和析构函数
1.2.1 构造函数
函数名和类名相同,没有返回值,也不能写void,创建对象时自动调用。
一般用来给类的字段或通过属性赋初值。
举例:
Public Person(string name,int age,string language){//有参数构造函数
this.Name = name;
this.Age = age;
this.language = “adfsad”;/ this.language =language;
}
此时,调用有参数的构造函数时,创建对象时应加上参数,如下:
Person p1 = new Person(“dfasd”,23,”sfda”);
this是代表当前对象
不写构造函数时,会自动调用一个系统给的无参数的构造函数,自己写了会把系统给的覆盖掉,也就意味着,自己如果写了有参数的构造函数,实例化对象时,必须同时给予参数初始化字段,否则就得再写一个无参的构造函数。
1.2.2 析构函数
对象销毁的时候,自动调用,释放内存。
多个对象时,每销毁一个调用一次
~Person(){//波浪号是析构函数的标志
Console.WriteLine(“析构函数”);//程序结束时会自动销毁对象,此时会输出这句话
}
1.3 静态与非静态
1.3.1 静态函数与非静态函数
[public] static void 函数名
C#的主入口函数是静态的,所以只能调用静态方法
静态的函数只能调用静态函数,静态的函数只能使用(非自己的,例如全局变量,自己函数作用域内非静态也可以)静态的字段、属性或方法。
非静态的类中,可以有静态成员和非静态成员,非静态类调用类中静态方法,依然用类名.方法名
非静态类调用方法字段和属性时只能用对象来调用。
静态函数和字段的调用方式是用类名.方法名或字段名,而且只能使用类名
实例函数中即可使用静态,也可使用非静态
1.3.2 静态类
[public] static class 类名
静态类只允许有静态成员,但可以有常量(常量不分静态非静态),静态类不能实例化。
静态类的作用:
静态类一般用来作为工具类,可以进行数据共享(相当于全局作用域),静态类占用内存,所以在项目中静态类越少越好。
1.4 结构体和类的区别
1.4.1 结构体:
Public struct Student{
字段
属性
函数
构造函数,有默认无参,但是不能人为的手写无参构造,有参构造也不会覆盖默认无参(没有参数也没代码,必须有参数),全字段赋值(函数内所有字段都必须赋值,只赋值部分不行)
没有析构函数
}
结构体可以继承接口,不能继承类和结构体。
结构体的调用:Student s; s.属性/方法;字段属性或方法只要是public,不实例化也可以调用,默认不写的不是public
结构体可以实例化。
Student s = new Student();
调用构造必须实例化。
1.4.2 类:
Public class Student{
字段
属性
函数
构造和析构函数
}
类内可以写结构体,但一般不会这么写
类是引用类型,存在堆中,传递地址。
结构体值类型,存在栈中。
1.5 命名空间
Namespace
命名空间相当于类的文件夹,可以避免类的重名。
不在同一命名空间的类可以重名,因为不在同一空间内。
如果类名和系统的类同名,不会报错(因为命名空间不同),但是此时只能调用自己的类,无法再调用系统命名空间的类了。
如果想用其它命名空间的类,需要引用对应的命名空间。
Vs中,在项目中右键引用,选择解决方案,选择对应的命名空间引用。同时在代码中写入using命名空间名;举例:using System;
快捷键引入命名空间,alt+shift+F10
1.6 继承
解决冗余代码,把重复的成员封装成一个类,作为父类
语法:
类名:父类{
}
举例: public class Student:Person(基类,被继承类){
}官方称呼:继承类,被继承类
C#是单继承(单根性),一个类只能继承一个类,但是可以被多个类继承,可以有多道继承(传递性),但最好不要超过三个继承。
子类继承父类后,只能使用父类的公有字段或方法,不能继承私有的。
子类实例化会默认调用父类的无参构造,但是不会继承父类的有参数构造。
子类调用父类的构造函数,使用关键字 :base();
Base将参数的数值传给了父类的构造函数
举例:
Public student(sting name,int age,string hobby):base(name,age){//子类构造函数
This.Hobby = hobby;//name和age就不需要再写了,那两个通过base传递给了父类的构造函数
}
Public student(sting name,int age) {//父类构造函数
This.Name = name;
This.Age = age;
}
所有的类都继承与object类
Vs命名空间右键,查看类图
1.7 Protected访问修饰符和new关键字
1.7.1 Protected
protected关键字,只能父类和子类中使用
1.7.2 new
new关键字实例化对象时,会覆盖父类的同名成员;
如果是故意隐藏,就在类名前加上new关键字,不写不会报错,但是编译器会提醒
1.8 里式转换
1、子类可以赋值给父类
举例
Person s = new Student();student为子类,person为父类。
如果有函数需要一个父类类型的值,我们可以给他一个子类,举例
String.Format(“fgsfd”,5);格式化字符串函数需要一个object类型的参数,给他int类型也不会报错。因为所有类型都是object类的子类。
2、如果父类里存的是子类对象,我们可以将这个对象强制转换为子类的对象。举例:
Person p = new Student();//此时父类person中存的是student的对象
通过is和as关键词
Is表示类型转换,如果能转返回true,否则false,用于判定
If(p is student){//判断是否能转
Student ss = (Student)p;强制转换
}
As如果能转就直接返回转换过的对象,否则返回null。(又称安全型转换)
As的用法
Student ss = p as Student;
注意:父类得对象可以直接转换为子类对象,其实对应里式转换第一条,父类的变量和函数参数,可以赋值子类的对象。
Person[] p = new Person[10];
P[0] = new Student();此时p[0]为student的对象。
因此可以for循环写
For(int i=0;i<p.Length;i++){
P[i] = new Student();
P[i].sayhello();//此时是student的对象
}
1.9 This的用法
This除了代表当前对象外,还有另一种用法:用this指向自己本类的构造函数
比如,当构造函数有多个时,其中有个参数最全,我们就可以通过this直接使用参数最全的构造函数初始化。写法如下:
Public Person(int age):this(age,”0”){
}
Public Person(int age,string name) {
This.name = name;
This.age = age;
}
2 第十天
2.1 多态(虚方法、抽象类、接口)
2.1.1 虚方法(只用于父类子类的继承关系)
virtual 父类中标记方法为虚方法。
子类中使用 override重写,此时虚方法可以重写,也可以不重写。
重写后,调用时就会调用本身的方法。
例如:
Person中有方法sayHi(){cw(“我是父类”)}student为继承,student中有方法sayHi(){
Cw(“我是子类”);
};
Public virtual void sayHi(){cw(“我是父类”);}
Public override void sayHi(){Cw(“我是子类”);}
Student s1 = new student();Student s2 = new student();Person p1 = new person();
Person[] p = new person[2]{s1,s2,p1};
P[0]/p[1].sayHi();//此时输出的是我的子类,不需要再进行is或者as判断转换了。
P[2].sayHi();输出依旧是我是父类
子类的子类(孙子类)没有重写虚方法时,直接调用会调用爷爷类?的方法。
2.1.2 抽象类和抽象方法
abstract抽象类和方法都是用该字段标志,共同特性比较多,差异较小的时候可以使用抽象类。
例如:public abstract class AA{ }
抽象类无法被实例化。抽象类也可以有实例成员,即正常的方法和属性字段,并且该类方法和属性字段也可以被继承
抽象类除了做父类,也可以做子类继承抽象类,也能继承普通类
抽象方法
父类的方法不知道如何是实现时,可以将方法写成抽象方法,但没有方法体。
public abstract voidVoice();没有大括号
抽象方法可以在抽象类和接口,抽象方法必须要重写,签名(返回值和参数)要一致。
不能有抽象的字段,可以有抽象的属性、方法、事件。
2.1.3 接口
接口就是一种规范(或者说一种能力)
关键字:interface
接口中可以有属性,方法,索引器,事件。
接口成员不能有访问修饰符,默认public;接口的方法不能有具体实现;
举例:(一般接口名大写I开头)
Public interface IFly(){
Void fly();
Void run();
}
接口的方法不能有具体实现,需要到具体类中实现,继承了接口的类中必须将接口中的所有方法都实现了。
public class Bird:IFly{
public void fly(){
}
public void run(){
}
}
接口不能实例化
一个类可以继承多个接口,例如:
public class Bird:IFly,IChiBang{}
一个类可以继承另一个类的同时也可以继承接口,但是类必须写在前面,接口写在后面,用逗号分隔。例如:
Public class Bird:Animal, IFly,IChiBang{ }
接口可以继承接口,但不能继承类,继承接口的接口继承的方法不能实现,一般不会这么用。
如果继承接口的类中有和接口同名的方法,可以直接使用该同名方法作为接口的实现,也可以再单独实现接口:举例
public class Bird:IFly {
public void fly(){//类中原有的方法
}
Void Ifly.fly(){//实现接口的方法(显示实现接口),不通过这种方式,原同名方法会被默认为接口的实现方法。
}
}
上述情况接口的fly方法调用:Ifly f= new Bird();f.fly();
原有方法的调用:Bird b = new Bird();b.fly();
2.1.4 抽象类、接口和虚方法的使用区别
如果父类中的方法有实现,并且父类需要被实例化时,适用普通类,采用虚方法来实现多态。
如果父类中方法没有默认的实现方式,父类也不要被实例化,共同特性比较多的时候,可以将该类定义为抽象类。
共同特性比较少的时候,个体差异极大,可以使用接口。
2.2 装箱和拆箱
本质就是类型的转换。
将值类型转化成引用类型叫装箱
将引用类型转换值类型叫做拆箱
发生拆装箱的前提是转换类型的两者具有继承关系,object是所有类型的父类
例如:int a = 3;
Object b = a; //装箱(可以执行,结果正确,因为object是所有类型的父类)
Int c = (int)b;//拆箱;
2.3 值传递和引用传递
值类型传递传递值和地址
引用类型传递是传递的地址,所以引用类型通过赋值传递后,修改一个,另一个也会改变,例如数组。
类是引用类型,类中的值类型是存在堆中的。方法里的值类型是存在栈里。
引用类型在栈中和堆中都存有地址,且两个地址不同。
字符串是引用类型,但字符串有不可变性。
例如:string str1 = “cctv”;string str2 = str1; str1 = “cc”;
此时,str1 = “cc”; str2 = “cctv”;
因为字符串的不可变性,导致字符串定义后会开辟两个空间,虽然是引用传递,但修改其中一个的值不会改变另一个。
- 自己用的C#基础学习笔记(二)——C#面向对象(1)
- 自己用的C#基础学习笔记(二)——C#面向对象(2)
- 自己用的C#基础学习笔记(二)——C#面向对象(3)
- 自己用的C#基础学习笔记(一)——C#面向过过程
- C#面向对象基础(二)
- C#面向对象基础学习笔记
- 【黑马程序员】c#面向对象的基础(学习笔记)
- C#学习笔记4——简单的面向对象
- C#学习笔记——面向对象、面向组件以及类型基础
- C#面向对象设计模式纵横谈学习笔记(1)
- C# 面向对象设计基础 二(上)
- C# 面向对象设计基础 二(中)
- C# 面向对象设计基础 二(下)
- c# 面向对象笔记(1)
- C#面向对象的基础
- C#学习笔记之——面向对象编程
- C#学习笔记(三):面向对象和类
- 《C#入门经典》学习笔记(面向对象编程)
- 腾讯首席工程师:程序员成长之道
- 浅谈Java内存模型、并发、多线程
- JAVAEE开发接入微信公众号接口初解(1)
- Oracle之 11gR2 RAC 修改监听器端口号的步骤
- 最小生成树:Prim算法
- 自己用的C#基础学习笔记(二)——C#面向对象(1)
- 程序员面试失败的原因
- SVG精髓-笔记与实践
- RocketMQ原理解析-broker 4.HA & master slave
- BouncyCastle使用
- 数据结构与算法学习总结-线性表基础
- Ubuntu 16.04 常用软件安装命令
- 生成一段号段的mac
- 综合练习一