- 
            
            1、泛型类就是一个模子,放入类型的材料(字段属性方法),可以塑造出想要的产品。 
 2、语法
 class Cage<T>//这是一个笼子类和泛型类,类名后加上一对<>,加上一个泛型参数
 {
 T[] petArray;//定义T类型的数组
 public void PutIn(T pet){···}//放入T类型的宠物
 public T TakeOut(int index){···}//占位符T,cage类变为具体类时,T相应的变成具体数
 }
 //实例化
 var dogCage=new Cage<Dog>();//得到狗狗笼子
 var catCage=new Cage<Cat>();//得到猫咪笼子
 3、为什么需要泛型,用基类(包括所有类的基类object)或者公共的接口也可以实现一个Cage类,但是类型太宽泛,需要显示转换类型并判断真是类型是什么。
 4、泛型使用:声明一个泛型类->引用泛型->构造实例
 class Cage<t>{···}
 class Cage<Dog>{···}
 dogCage=new Cage<Dog>;
 比如不写Petcage<Dog> dog=new Petcage<Dog> ("名字");而用一个从来没见过的 var代替。还有 return default<T>也没解释啥意思
 理解:泛型就是在不确定类的参数类型和返回类型时,设置一个变量来代替这个固定的类型。当创建类实例时,在给这个变量赋对应类类型值,这样就可以实现一个类,输出不同类型的值和方法。
 不用老师的例子,用一个给数组赋值输出数组的例子更好理解;如设置一个类,构造函数初始化一个数组数组类型为int,有给数组赋值方法和获取数组值的方法,在此注意:数组的类型int和获取数组值的方法的返回值类型都为int,如果实例此类调用方法,实参和返回值类型也必须是int;就此限定死了此类的实例; 如果想要一个设置char类型的实例,还得必须创建一个新的char的类和方法才能实现;这样代码工作量很大;若使用泛型,用变量<T>代替固定类型int或char,这样在实例化的时候,将T赋不同类型(int、double、char)就可以获得想要的返回值类型,从而实现了一个模板,只变一个参数T就能实现相同的功能
 上面给出的例子。只需要把所有<T>去掉,后面的T全改为int或char 就能变为普通类了。对比理解非常简单了查看全部
- 
            
            1、什么是重载运算符 不能创造新的运算符,所以利用现有的某种运算符,针对自定义类或者结构(预定义类型和现有运算符的运算含义是确定的所有不能更改),定义某种运算符(该运算符和该操作具有一定相关性,如公狗狗+母狗狗=新生狗狗),从而简化自定义类型的操作。 为什么需要重载运算符:利用现有运算符,简化自定义类型的操作。最好是,该运算符和该操作,具有一定亿相关性。 2、语法细节 
 public static Dog operator +(Dog male,Dog female)//如公狗狗+母狗狗=新生狗狗
 {
 ···
 }
 3、哪些运算符可以重载
 一元运算符:+、-、!、~、++、- -、true、false(操作数必须是类和结构)
 二元运算符:+、-、*、%、&、|!、^、<<、>>、= =、!=、>、<、>=、<=(两个操作数至少有一个表示类或者结构)
 不能重载:=、&&、||、[](索引操作)、()等
 4、重载运算符不能做什么
 创造新运算符
 改变运算符语法
 重定义运算符如何处理预定义类型
 改变运算符的优先级和结合性
 5、重在运算符举例
 ···
 public void ShowAge()
 {
 Console.WriteLine("Age="+_age);
 }
 ···
 //重载自增操作,针对宠物的年龄
 public static Pet opertor ++(Pet pet)//返回值为Pet类型,参数为宠物自身。所有的重载方法都需要public static修饰
 {
 ++pet._age;
 return pet;
 }
 ···
 Dog dog=new Dog("Jack");
 dog._age=2;
 dog++;
 dog.ShowAge();查看全部
- 
            
            隐式转换语法public static implicit opertor Dog()(Cat cat){retuen new Cat(Dog dog);} 显示转换语法public static explicit operator Dog(Cat cat){...} 查看全部
- 
            
            1、装箱:根据值类型的值,在堆上创建一个完整的引用类型对象,并返回对象的引用,是一种隐式转换(语言自动完成)。 
 2、为什么要装箱
 有时候需要将值类型转化为引用类型(比如object)来进行统一的操作(比如作为函数的参数)和统一的存储(比如object[])。
 3、装箱简单实例
 int i=3;
 object oi=null;
 oi=i;//发生装箱,原来的int保持不变,创建了一个新的对象,该对象在堆当中。需要性能消耗的。
 4、装箱的本质
 就是在对上创建了一个引用类型的副本,新创建的引用类型和原来的值类型相互独立。
 相互独立代码验证:
 int i=3;
 object oi=i;//发生装箱
 Console.WriteLine("i="+i+",oi="+oi.ToString);//输出为i=3,oi=3
 oi=10;
 i=7;
 Console.WriteLine("i="+i+",oi="+oi.ToString);//输出为i=7,oi=10, oi存储在堆中, i存储在栈中
 说明两者相互独立
 5、拆箱
 将装箱后的对象转化回值类型的过程,是一种显示转换(需要手动干预)。
 6、拆箱实例
 in i=3;
 object oi=i;//装箱
 int j=(int)oi;//拆箱 通过强制转换Console.WriteLine("j="+j);//输出10 查看全部
- 
            
            1、静态类 包含静态属性和方法,被标记为static 
 静态类不能创建实例,不能被继承。
 可以为静态类定义静态构造函数。
 2、作用
 主要用于基础类库(math类)和扩展方法。
 3、如何扩展方法
 若有源代码,直接添加一个新方法
 如果不能修改单也不是密闭类,可以派生子类扩展
 如果以上条件不满足,可以使用静态类扩展方法
 3、在静态类中的静态方法中参数中加入this关键,则可以直接利用对象调用方法就可以。static class PetGuide//扩展Dog类的方法 
 {public static double HowToFreedDog(this Dog dog){...} { 
 Console.WriteLine("播放如何喂养一直狗狗的视频");
 }
 }Dog dog=new Dog("Tommy"); dog.HowToFreedDog(); 
 4、总结扩展要求
 扩展方法所属的类,必须是static类
 扩展方法本身就是static方法
 扩展方法的第一个参数类型,必须是this+类名。
 例如:
 Dog类没办法修改,修改Dog类就需要扩展方法,需要一个喂养宠物的方法
 static class PetGuide//扩展Dog类的方法
 {static public void HowToFreedDog(this Dog dog) { 
 Console.WriteLine("播放如何喂养一直狗狗的视频");
 }
 }
 ···
 Dog dog=new Dog();//Dog类中没有HowToFreedDog();方法
 dog.HowToFreedDog();//扩展之后好像Dog类中有这样的方法一样。查看全部
- 
            
            静态类和静态成员 
 1、类的静态成员
 成员被标记为static时,就是静态成员。静态成员将会被类的所有实例共享,所有实例都访问统一内存位置。
 静态成员跟实例成员分开存放。静态成员存放在堆中。class Dog{static int Num;}2、静态成员访问 
 直接通过类名访问,普通成员需要通过实例访问。3、静态成员声明周期 
 独立任何实例,没有实例也可以访问。静态成员使用之前编译器已经帮忙完成初始化。
 4、静态函数不能访问实例成员,仅能访问其他静态成员,普通方法可以访问静态成员
 5、静态构造函数class Dog{static public void PrintNum(){Console.WriteLine(“Num=”+Num);}}用于初始化静态字段 
 在引用任何静态成员之前,和创建任何实例之前调用。
 与类同名,使用static,无参数,没有访问修饰符,普通构造函数可以重载的.
 静态函数只能访问静态成员,非静态函数可以访问静态/非静态成员class Dog//类名 {static Dog()//静态构造函数,与类同名,无参数,无访问修饰符 {num=0;//只能访问静态成员 } } 查看全部
- 
            
            结构和类 
 1、不同点
 结构是值类型(在栈中),类是引用类型(在堆中)
 结构不支持继承,类支持继承
 结构不定义默认构造函数,编译器会定义
 2、适用场合
 结构由于分配内存快,作用域结束即被删除。不需要垃圾回收,用于小型数据结构,传递过程会复制,应该用ref类参数传递提高效率。
 类用于其他需要继承体系的场合。
 例如:定义食物是一个不需要长期存储的数据类型,吃完就没有了,所以可以定义一个食物struct关于堆和栈内存: 栈内存:栈内存首先是一片内存区域,存储的都是局部变量,凡是定义在方法中的都是局部变量(方法外的是全局变量),for循环内部定义的也是局部变量,是先加载函数才能进行局部变量的定义,所以方法先进栈,然后再定义变量,变量有自己的作用域,一旦离开作用域,变量就会被释放。栈内存的更新速度很快,因为局部变量的生命周期都很短。 堆内存:存储的是数组和对象(其实数组就是对象),凡是new建立的都是在堆中,堆中存放的都是实体(对象),实体用于封装数据,而且是封装多个(实体的多个属性),如果一个数据消失,这个实体也没有消失,还可以用,所以堆是不会随时释放的,但是栈不一样,栈里存放的都是单个变量,变量被释放了,那就没有了。堆里的实体虽然不会被释放,但是会被当成垃圾,Java有垃圾回收机制不定时的收取。 查看全部
- 
            
            接口 
 1、接口就是制定一组函数成员,而不实现他们的引用类型,用interface声明。接口函数不能用其他访问修饰符修饰,默认为public。interface ICatchMice{void CatchMice();} 2、接口只能用来被实现 
 例如 Cat:ICatchMice{ public void CatchMice(){...}
 //实现接口函数
 }Cat c=new Cat(); ICatchMice ic=(ICatchMice)c; c.CatchMice(); //通过对象调用 ic.CatchMice(); //通过接口调用 3、一个类可以实现多个接口,当一个类同时继承基类和实现接口时,应该将基类写在最前面,用逗号隔开 可实现多个接口 Cat:Pet ,ICatchMice,IClimbTree //基类 接口1 接口2 { public void CatchRat(){}. public void ClimbTree()} ... } 4、一个类实现接口时,必须实现接口声明的函数。 
 5、可以通过接口引用调用接口中的方法,也可通过实例调用接口方法。例子
 爬树为一个接口,抓老鼠为一个接口,当猫这个类实现这两个接口时,
 Cat c=new Cat("tom");
 爬树 ci=(爬树)c;
 c.pashu();//通过实例调用接口方法
 ci.pashu();//通过接口引用调用接口方法查看全部
- 
            
            密闭类 密闭方法 sealed override public void Speak(){} 查看全部
- 
            
            派生类调用基类的构造函数 查看全部
- 
            
             扩展想扩展类的方法 查看全部
- 
            
             抽象 查看全部
- 
            
            依赖倒置原则,程序尽量依赖于抽象类  查看全部 查看全部
- 
            
             隐藏方法  查看全部 查看全部
- 
            
            优点  查看全部 查看全部
举报
 
             
         
                