多态 虚方法 抽象类 泛型

来源:互联网 发布:正版oracle数据库价格 编辑:程序博客网 时间:2024/05/29 18:33

.NET基础加强

 规则(法律,必须遵守否则报错)

语法

规范(道德,大家都喜欢有道德的人。)

注释

骆驼命名 :第一个单词首字母小写,之后的单词首字母大写 userNameuserPasswordrealName(普通变量、字段)

帕斯卡命名:第一个单词首字母大写,之后的单词首字母大写 GetMax()ChangeName()…(方法名、类名)

定义的变量或者方法 名字要有意义。

方法名:动词。Write()Open()Close()Dispose()GetUserId()、…(方法都是要做一件事情)

变量名:按功能命名、按方法的返回值内容命名userName=GetUserName();

 

基础复习

 

1.1 交换俩个变量

补充:1.启动项保存位置在哪里?.csproj

1.2 求两个数中的最大值

1.31-100之间所有奇数的和

补充:1.按两下Tab键,自动生成代码段

自动增加一个Person

1.4 求数组中的最大值

补充:

1.方法:有没有参数?有没有返回值

2.自动生成方法存根 shift+alt+F10 或者Ctrl+.

3.文档注释的显示位置 在哪里?

4.代码说明书

1.5 日期格式转换

补充:处理10的问题

1.6 类 属性 继承

补充:

1.单独新建一个cs文件来写类,类的名字和文件名一致,这样方便代码的维护 

2.字段的显示为蓝色方块 

3.属性的显示为 小手 

4.方法的显示为 红色方块 

5.封装字段,光标停在字段中 按 Ctrl+R+E

6.Reflector 反编译工具

7.用于实现框架 

 面向对象 

封装 

把变化的东西封装起来

类的访问修饰符默认:internal

类中的成员如果不写访问修饰符默认是private.

protected 当前类及子类中可以访问(在继承中用。)

*internal 当前程序集内部可以访问

protected internal 当前程序集或子类中(不同程序集也可以访问)。

成员变量使用前如果不赋值,默认会有一个初始值。

stringnullint0boolfalse

 继承

2.1在这里指类与类之间的关系

如何判断一个继承关系是否合理?子类 is a 父类。

 

为什么要继承?继承带给我们的好处?

代码重用

LSP里氏替换原则、多态。(程序的可扩展性、灵活性)方法重写override。虚方法的原理:虚方法表。

子类继承父类的属性和方法,使创建子类变得很简单,实现了代码重用、以及多态。

类的单根继承性、传递性、继承时构造函数的问题。构造函数不能被继承。

所有的类都直接或间接的继承自object。查看IL代码。

 

2.2对象初始化器

2.3关于继承的那些事儿 

protected  
只能在子类内部和当前类内部中使用
可以在类内部以及所有子类中(内部)访问。
this:
1.作为当前类的对象,可以调用类中的成员。this.成员(调用成员,自己)
2.调用本类的其他构造函数。:this()(调用构造函数,自己)
base
1.调用父类中的成员(调用成员,父类)base点不出子类独有成员。
2.调用父类中的构造函数(调用构造函数,父类)
当调用从父类中继承过来的成员的时候,如果子类没有重写则this.成员;与base.成员;没有区别。如果子类重写了父类成员,则this.成员;调用的是子类重写以后的。base.成员;调用的依然是父类的成员。
子类构造函数必须指明调用父类哪个构造函数

2.4练习 +关于继承中“私有成员”能否被继承的问题 

 类中的成员如果不写访问修饰符默认是private.

2.5访问级别约束

虚方法静态类

3.1实现多态的手段1—虚方法virtual

虚方法可以给父类中的方法一个实现,比如ToString()方法
虚方法必须有实现部分,哪怕是空实现。

3.2静态成员-拖过类名访问、实例成员-通过对象访问

只能通过类名访问
静态方法中只能访问静态成员,或通过对象访问实例成员。
多个对象共享同一个静态成员。

3.3什么时候使用静态成员、静态类

静态类(一般都用作工具类,里面都是一些工具函数)

3.4静态类的继承问题 

 静态类不能被其他类继承
静态类只能继承自Object类。(静态类不能继承自其它类。)
继承(多态)、静态本身就是相反的。

第四课 多态

4.1为了实现程的可扩展性

  多态的作用:把不同的子类对象都当作父类来看,可以屏蔽不同子类对象之间的差异,写出通用的代码,做出通用的编程,以适应需求的不断变化。

4.2实现多态的方式 1 抽象类abstract 

1抽象成员木有(成员实现)标记为 abstract大括号,小括号后面直接加分号,2抽象成员必须写在抽象类中3子类继承时必须重写父类中的抽象成员(子类也是抽象类除外)4抽象类也不能被实例化,可是有构造函数

用虚方法还是抽象类实现多态,要看父类是否需要被实例化或父类中的方法有没有默认的实现。 

4.3 抽象类练习

 

   public  abstract class Animal    {       public abstract void Eat();       public abstract void Bark();    }


4.4面向对象计算器

 

里氏替换原则-类型转换

当需要一个父类对象的时候,可以给一个子类类型的对象;反之不可。

子类→父类,发生了隐式类型转换,反之,已知父类由子类转来,可强制显示转换父类为子类。若不确定被转父类是否有子类,可用AS,最多返回空值,不会像强转那样报异常。

    public  abstract class Animal
    {
       public abstract void Eat();
       public abstract void Bark();


    } 

 通过抽象方法实现多态

 

 接口

 

1. 如何使用virtualoverride

Person per = new Student();

per.SayHI()调用的子类重写的SayHi方法(语法、应用(多态))

2. 如何使用abstractoverride

3. “方法重载overload” 、 “方法重写override"、 "隐藏new"是同一个概念吗?

4.抽象类和接口的区别?见备注1.

抽象类适用于同一系列,并且有需要继承的成员。

接口适用于不同系列的类具有相同的动作(行为、动作、方法)。

对于不是相同的系列,但具有相同的行为,这个就考虑使用接口。

接口解决了类不能多继承问题。

 

 枚举 

结构 

类型转换  

值类型 引用类型

 

5课 异常处理

 

6课 可变参数

 

字符操作

 

1课 字符串

 

字符串的一些特性:不可变性(ToUpper演示)、字符串池(针对字符串常量)、(*用的少)字符串留用(Intern,针对变量常量,见备注1)。

String 字符串,字符串可以看成字符数组,不可变特性(通过for循环,修改string中的元素,失败!)

属性

Length //获得字符串中字符的个数。”aA我你他”→5

方法

IsNullOrEmpty() 静态方法,判断为null或者为””

ToCharArray() 将string转换为char[]

ToLower() 小写,必须接收返回值。(因为:字符串的不可变);

ToUpper()      大写。

Equals()     比较两个字符串是否相同。  忽略大小写的比较,StringComparation.

IndexOf() 如果没有找到对应的数据,返回-1.//面试题:统计一个字符串中,”天安门”出现的次数。

LastIndexOf() 如果没有找到对应的数据,返回-1

Substring() //2个重载,截取字符串。

Split()   //分割字符串。

Join() 静态方法

Format () 静态方法

Replace()  

Trim()

 

 集合操作

垃圾回收

.net中垃圾回收机制:mark-and-compact(标记和压缩)
除了内存资源外的其他资源怎么办?~或者Dispose()
弱引用:WeakReference,对于创建比较耗时的对象可以使用若引用。见备注1.
垃圾回收 
作用:提高内存利用率  
条件1引用类型2无变量引用 
方式 三代

集合

一、集合类(增、删、查、改、遍历)

数组特点:类型统一、长度固定。

集合常用操作 添加、遍历、移除

命名空间System.Collections 

ArrayList 可变长度数组,使用类似于数组

属性 

Capacity(集合中可以容纳元素的个数,翻倍增长); 

Count(集合中实际存放的元素的个数。)

方法 

Add()  

AddRange(Icollection c)  

Remove() 

RemoveAt() 

Clear() 

Contains()  

ToArray() 

Sort() 排序

Reverse();//反转

二、Hashtable键值对集合

Hashtable 键值对的集合,类似于字典,Hashtable在查找元素的时候,速度很快。 

Add(object key,object value);

hash[key]

hash[key]=“修改”;

.ContainsKey(key);

Remove(key);

遍历:

hash.Keys

hash.Values/DictionaryEntry

键值对集合中的“键”,绝对不能重复。

 

案例:两个(ArrayList)集合a,b,c,d,e}defgh” },把这两个集合去除重复项合并成一个。

案例:随机生成101-100之间的数放到ArrayList中,要求这10个数不能重复,并且都是偶数(添加10次,可能循环很多次。)

Random random=new Random();

random.next(1,101);//随即生成1-100之间的数。

练习:有一个字符串是用空格分隔的一系列整数,写一个程序把其中的整数做如下重新排列打印出来:奇数显示在左侧、偶数显示在右侧。比如”2 7 8 3 22 9 5 11”显示成”7 3 9 2 8 22.”。

 

注意事项:不要把Random的实例化放到循环里面!

可以使用两个集合来降低产生随机数的循环次数。 

Random在循环中会降低执行效率(每次new的时候的种子是一样的,当前时间。)(*) 

第3课 泛型集合:使用泛型集合

命名空间System.Collections.Generic

List<T>类似于ArrayListArrayList的升级版。

各种方法:Sort()Max()Min()Sum()

Dictionary<K,V>类似于HashtableHashtable的升级版。

推荐使用泛型集合。

T,K,V就像一把锁,锁住集合只能存某种特定的类型,这里的T,K,V也可以是其它字母 

泛型集合可以进行foreach遍历,是因为实现了IEnumerable<T>具有了GetEnumerator()方法

先看foreach的本质。(*

 

案例:把分拣奇偶数的程序用泛型实现。List<int>

练习1:将int数组中的奇数放到一个新的int数组中返回。

练习2:从一个整数的List<int>中取出最大数(找最大值)。别用max方法。

练习:把123转换为:壹贰叁。Dictionary<char,char>

string str = "0零 1壹 2贰 3叁 4肆 5伍 6陆 7柒 8捌 9"; 

练习:计算字符串中每种字符出现的次数(面试题)。 “Welcome to Chinaworld”,不区分大小写,打印“W2”“e 2”“o 3”…… 

提示:Dictionary<char,int>,char的很多静态方法。char.IsLetter()

案例:简繁体转换 。Dictionary

课下练习:英汉翻译。WinForm做。发英汉词典txt

课下练习:火星文翻译器。发字库。(作业。)

案例:编写一个函数进行日期转换,将输入的中文日期转换为阿拉伯数字日期,比如:二零一二年十二月月二十一日要转换为2012-12-21(处理“十”的问题:1.*月十日;2.*月十三日;3.*月二十三日;4.*月三十日;)4中情况对“十”的不同翻译。110213→不翻译;40【年部分不可能出现’十’,都出现在了月与日部分。】

测试数据:二零一二年十二月二十一日、二零零九年七月九日、二零一零年十月二十四日、二零一零年十月二十日

 自定义泛型

泛型的目的:还是代码重用。T:一般叫做“类型参数”,把数据类型作为参数传递。一般用T类表示或者以大写T开头的比如:TKey,TValueTOutputTResult

泛型,在.net2.0版本才开始引入。

泛型类、泛型接口、泛型方法、泛型委托(*)

===============使用where关键字进行类型约束=====================

 装箱、拆箱

比较泛型集合List<T>ArrayList的性能。循环增加整数、引用类型比较性能。(装箱、拆箱 )见备注。

//1.装箱、拆箱必须是: 值类型→引用类型  或  引用类型→值类型。

            //object,接口。值类型是可以实现接口。

            //Person p=new Student();//这个叫隐式类型转换,不叫装箱。

            //Student stu=(Student)p;//这个叫显示类型转换,不叫拆箱。

            //int类型为什么能装箱到object类型,但不能装箱到string类型或Person类型,

            //因为object类型是int类型的父类。 

            //2.拆箱时,必须用装箱时的类型来拆箱

            //装箱时如果是int,拆箱必须用int,不能用double

 

 //3.方法重载时,如果具有该类型的重载,那么就不叫拆箱或装箱。

int n=10; Console.WriteLine(n);//没有发生装箱,因为方法重载。

//4.接口与值类型之间的装箱与拆箱。

            //5.字符串连接

            // string.Concat(s1, s2, n3, d4);判断是否发生了装箱,及次数。

 foreach

演示通过IEnumerator接口遍历序列。

GetEnumerator()方法。

foreach遍历修改数据???绝对不行。

//1.foreach循环是只读的。不能用来修改数据。

//2.foreach循环式只进的,并且是一条一条循环的。