@作者: 风不停息丶 学习笔记
一、命名空间
- 基本概念
是用来组织和复用代码的
像一个工具包 类就是工具都声明在命名空间中 (文件夹装文件)
命名空间可以分开写
同命名空间中类的名字不可以重复,不同命名空间的类可以同名
namespace Mygame
{
class Gameobject
{
}
}
//命名空间可以分开写
namespace Mygame
{
//属于同一命名空间 可以正常继承
class Player:Gameobject
{
}
}
- 不同命名空间中相互使用 需引用命名空间
- 两种方法 1.using关键字 2.点出来引用
using System
using Mygame
//使用Mygame命名空间的Gameobject类
Gameobject g = new Gameobject();
//使用Mygame命名空间的Gameobject类
Mygame.Gameobject g = new Mygame.Gameobject();
//也可以应对不同命名空间中 同名类的引用标识
using Mygame
using Mygame2
Mygame.Gameobject g = new Mygame.Gameobject();
Mygame2.Gameobject g2 = new Mygame2.Gameobject();
- 命名空间可以包裹命名空间
- 工具包的小工具包
namespace MyGame
{
namespace UI
{
class Image
{
}
}
namespace Game
{
class Image
{
}
}
}
//****************************************
//通过命名空间依次点出其中的类来使用
MyGame.UI.Image img = new MyGame.UI.Image();
MyGame.Game.Image img2 = new MyGame.Game.Image();
//或者引用命名空间时点出
using MyGame.UI;
using MyGame.Game;
- 总结
1.命名空间是个工具包用来管理类的
2.不同命名空间中可以有同名类
3.不同命名空间中相互使用需要using引用命名空间或者指明出处
二、万物之父object中的方法
- object的静态方法
1、静态方法:Equals
值类型判断 对比两个对象是否相等
引用类型判断 对比的是两个对象 是否指向同一内存地址,并不是判断是否是相同类型
2、静态方法:ReferenceEquals
比较两个对象是否相同的引用,主要是用来比较引用类型的对象。不能用来比值 很少用
- object的成员方法
1、成员方法:GetType
反射相关知识,c#进阶讲
2、成员方法:MemberwiseClone
浅拷贝:值类型直接复制过来,引用类型复制的是内存地址。所以改变拷贝后的值类型变量与拷贝前的值类型变量无关,改变拷贝后的引用类型变量 拷贝前的引用类型变量也会跟着改变
namespace Test
{
internal class Program
{
static void Main(string[] args)
{
Test t = new Test();
Test t2 = t.Clone();
Console.WriteLine("克隆对象后");
Console.WriteLine("t.i =" + t.i);
Console.WriteLine("t.t2.i =" + t.t2.i);
Console.WriteLine("t2.i =" + t2.i);
Console.WriteLine("t2.t2.i =" + t2.t2.i);
t2.i = 20;
t2.t2.i = 21;
Console.WriteLine("改变克隆对象后");
Console.WriteLine("t.i =" + t.i);
Console.WriteLine("t.t2.i =" + t.t2.i);
Console.WriteLine("t2.i =" + t2.i);
Console.WriteLine("t2.t2.i =" + t2.t2.i);
}
}
class Test
{
public int i = 1;
public Test2 t2 = new Test2();
public Test Clone()
{
return MemberwiseClone() as Test;
}
}
class Test2
{
public int i = 2;
}
}
- object的虚方法
1、虚方法:Equals
可以重写该方法定义自己的比较相等
2、虚方法:GetHashCode
极少使用
3、虚方法:Tostring
class Test
{
public override string ToString()
{
return "苏老师声明的Test类"
}
}
//*************************************
Test t = new Test();
Console.WriteLine(t.ToString);
//打印结果为"苏老师声明的Test类"
- 总结
三、String字符串
- string字符串常用方法
//字符串本质是char数组
string str = "苏同学";
Console.WriteLine(str[0]);
//打印结果为"苏"
//⭕转为char数组
char[] chars = str.ToCharArray();
//⭕获取字符长度
str.Length
//⭕字符串拼接
str = string.Format("{0}{1}",1,222);
//⭕正向查找字符位置
str = "我是苏同学?";
int index = str.IndexOf("苏");
//返回 2 字符串的索引 , 找不到就会返回-1
//⭕反向查找字符位置
str = "我是苏同学苏同学?";
index = str.LastIndexOf("苏同学");
//返回 5 从后面开始查找词组就返回第一个字的索引,找不到就返回-1
//⭕移除指定位置后的字符
str = "我是苏同学苏同学";
str = str.Remove(4);
//返回 "我是苏同"
//⭕执行两个参数进行移除 参数1开始的位置 参数2字符个数
str = "我是苏同学陈同学";
str = str.Remove(3,3);
//返回"我是陈同学"
//⭕替换指定字符串
str = "我是苏同学陈同学";
str = str.Replace("苏同学","李同学");
//返回"我是李同学陈同学"
//⭕大小写转换
str = "abcdefg";
str = str.ToUpper();
//返回"ABCDEFG"
str = str.ToLower();
//返回"abcdefg"
//⭕字符串截取 截取从指定位置开始之后的字符串
str = "苏同学陈同学";
str = str.Substring(3);
//返回 "陈同学"
//重载 参数1开始位置 参数2指定个数
str = "苏同学陈同学苏同学";
str = str.Substring(3,3);
//返回 "陈同学"
//⭕⭕字符串切割 指定切割符号来切割字符串
str = "1|2|3|4|5|6|7|8";
string[] strs = str.Split("|");
//返回 string[]{1,2,3,4,5,6,7,8}
四、Stringbuilder
- 解决多次修改string性能消耗问题
引用命名空间:System.Text
关键字:StringBuilder
容量问题 每次增加时都会自动扩容
无法直接重新赋值 要先清空再增加
完全具有引用类型的特征,没有值类型特征了
StringBuilder strBui = new StringBuilder("123123123");
//获得容量
int a = strBui.Capacity;
//默认为16现在已经用了9 自动扩容会x2 变成32 64 128....
- 增删改查替换
StringBuilder strBui = new StringBuilder("123123123");
//⭕增
strBui.Append("444");
//结果为 "123123123444"
strBui.AppendFormat("{0}{1}",555,666);
//结果为 "123123123444555666"
//⭕插入 参数1插入的位置 参数2插入的内容
strBui.Insert(0,"苏同学");
//结果为 "苏同学123123123444555666"
//⭕删 参数1删除开始的位置 参数2删除的个数
strBui.Remove(0,3);
//结果为 "123123123444555666"
//⭕清空
strBui.Clear();
//结果为 ""
//⭕重新赋值 先清空再增加
strBui.Clear();
strBui.Append("苏同学");
//⭕查 和数组一样
strBui[1];
//结果为 "同"
//⭕改 和数组一样
strBui[0]='李';
//strBui结果为 "李同学"
//⭕替换 参数1被替换的字符 参数2要替换的内容
strBui.Replace("同学","老师");
//strBui结果为 "李老师"
//⭕判断是否相等
strBui.Equals("李老师");
//返回为 true
五、结构体和类的区别
- 存储上的区别
结构体和类最大的区别是在存储空间上的,因为结构体是值,类是引用,因此他们的存储位置一个在栈上,一个在堆上 - 使用上的区别
结构体和类在使用上很类似,结构体甚至可以用面向对象的思想来形容一类对象
结构体具备着面向对象思想中封装的特性,但是它不具备继承和多态的特性,因此大大减少了它的使用频密
由于结构体不具备继承的特性,所以它不能够使用protected保护访问修饰符 - 细节上的区别
1.结构体是值类型,类是引用类型
2.结构体存在栈中,类存在堆中
3.结构体成员不能使用protected访问修饰符,而类可以
4.结构体成员变量申明不能指定初始值,而类可以
5 .结构体不能申明无参的构造函数,而类可以
6.结构体申明有参构造函数后,无参构造不会被顶掉
7.结构体不能申明析构函数,而类可以
8.结构体不能被继承,而类可以
9.结构体需要在构造函数中初始化所有成员变量,而类随意
10.结构体不能被静态static修饰,但结构体里的可以有静态成员(不存在静态结构体),而类可以
11.结构体不能在自己内部申明和自已一样的结构体变量,而类可以 - 结构体的特别之处
结构体可以继承接口因为接口是行为的抽象 - 如何选择结构体和类
1.想要用继承和多态时,直接淘汰结构体,比如玩家、怪物等等
2.对象是数据集合时,优先考虑结构体,比如位置、坐标等等
3.从值类型和引用类型赋值时的区别上去考虑,比如经常被赋值传递的对象,并且改变赋值对象,原对象不想跟着变化时,就用结构体。比如坐标、向量、旋转等等
六、抽象和接口的区别
- 抽象类和抽象方法
abstract修饰的类和方法
抽象类不能实例化
抽象方法只能在抽象类中申明是个纯虚方法必须在子类中实现 - 接口
interface自定义类型
不包含成员变量
仅包含方法、属性、索引器、事件,成员都不能实现,建议不写访问修饰符,默认public - 相同点
1.都可以被继承
2.都不能直接实例化
3.都可以包含方法申明
4.子类必须实现未实现的方法
5.都遵循里氏替换原则 - 区别
1.抽象类中可以有构造函数;接口中不能
2.抽象类只能被单一继承;接口可以被继承多个
3.抽象类中可以有成员变量;接口中不能
4.抽象类中可以申明成员方法,虚方法,抽象方法,静态方法;接口中只能申明没有实现的抽象方法
5.抽象类方法可以使用访问修饰符;接口中建议不写,默认public
- 如何选择抽象类和接口
表示对象的用抽象类,表示行为拓展的用接口
不同对象拥有的共同行为,我们往往可以使用接口来实现
举个例子:
动物是一类对象,我们自然会选择抽象类;而飞翔是一个行为,我们自然会选择接口。
看到这篇文章的小伙伴们可以点个赞👍支持一下,谢谢!