1.NET简单解说
l 面向对象提升
OOP(Object Oriented Programming)面向对象编程
AOP:(Aspache Oriented Programming):面向切面编程
OOD(Object Oriented Designer)面向对象设计(架构师) 3万/month
OOA(Object Oriented Analysis)面向对象分析 (分析师) 10万/month
DBA(Database Administrator,简称DBA)
l 泛型集合对对象数组的一个升级(真正的开发中,用的都是泛型集合)
l xml解析
如何将硬盘上的xml文件形成内存中的泛型集合数据
l IO操作
序列化与反序列化(应用很广泛)
l 大家对.NET的认识
Vs版本 .NET Framework版本
Vs2003 1.0/1.1
Vs2005 2.0
Vs2008 3.0/3.5
Vs2010 4.0
Vs2012 4.5
Vs2013 4.5
Vs2015 待测、
2.Microsoft .NET框架概述。
01,Microsoft .NET介绍
微软的.NET历史
2000年微软公司向全球宣布其革命性的软件和服务平台:Microsoft .NET
02,为什么需要.NET框架
通过如下两个问题说明为什么需要.NET框架
001,C#程序可以在不同平台(PDA、PC)的环境中运行吗?
002, 使用C#程序可以调用VB.NET开发的程序吗?
答案肯定是可以的,这也足以说明.NET框架的强大之处。
03,.NET框架概述
.NET框架
.NET战略的基础框架
.NET程序的运行环境
强大的类库
.NET 框架==.NET Framework
解析:在A机器上开发了一款软件,只要B机器上有框架就行了,不用再B机器上安装开发环境VS。
.net core 1.0
04,.NET框架的魅力
001,面向对象编程
提高软件可复用、可扩展、易维护性、灵活性
002,强大的动态web支持
003,web服务
例如:天气预报服务iGoogle和支付宝网上购物商城
003,数字身份验证的支持
004,支持构建.NET程序的炫彩外衣(特效制作)
3.NET框架体系结构
01.NET框架体系结构
ADO.NET概念?
解析:ADO.NET是微软提供的一组类库,可以帮助程序员和数据库交互。他里面有四大对象(DataReader,DataAdapter,Command,Connection).
直接提问
二年:世界上有两种人:能看懂二进制的人和不能看懂二进制的人
02,公共语言运行时
\
CLR的两个组成部分
CTS:称为通用类型系统
定义了在IL中的数据类型
CLS:称为公共语言规范
包括几种面向对象的编程语言的通用功能。
03,.NET框架类库
Scanner
Arrays
1.NET平台下的语言
01.C# VB J# F# C++
2.
vs2013 4.5
vs2012对应框架的版本是4.5
vs2010 4.0
vs2008/sp1 3.0/3.5
vs2005 2.0
vs2003 1.1
3..NET FrameWork两大组件是什么?
解析:.NET 框架类库(FCL:FrameWork Class Library)和公共语言运行时(CLR:common language Runtime)
4.CLR包含两部分:
解析:公共语言规范CLS(Common Language Specific) 通用类型系统CTS(Common Type System)
5.c#语言要编程成可以被CPU解析执行的代码需要两次编译:
第一次编译:将C#语言通过c#编译器编译成MSIL中间代码
第二次编译:将MSIL代码通过即时编译器(JIT)编译成CPU可以解析执行的代码,或者成为(平台专用代码)
6.java程序要想被CPU解析执行也是需要两次编译
一次编译:将后缀名为java的文件通过java编译器编译成后缀名为.class(字节码)文件
第二次编译:将.class文件通过java虚拟机(jvm)编译成CPU可以解析的代码
7.CLR里面至少三部分:
CTS
CLS
JIT
类库:可以看成是一个承载了N个类的容器。
类库:System.Data.SqlClient 和数据库交互
System.Data: DataSet
System.WinForms; Winform应用必须类库
System.Collections.Generic; 泛型集合
System.Net; 网络操作,下载等操作
System.IO; 文件的读写,文件夹的读写。遍历等操作
System.Drawing; 绘制图形,和验证码
类库和命名空间?
解析:一个类库一般对应一个命名空间,也可以对应多个。
可执行文件
dynamic link library
类库
4.封装体现
第一种:将私有字段封装成公有的属性看成是封装的体现
第二种:一个类可以封装属性和方法
public class Dog
{
private string name;
public string Name
{
get{return name;}
set{name=value;}
}
public void bark()
{
}
}
1.面向对象编程三大特性:封装、继承和多态
5..那些年我们学过的访问修饰符??
public:任何位置,包括跨程序集。
internal:在当前程序集(项目)中都可以访问
private:只能在当前类中访问(当前类的花括号中访问。)
protected:只能在当前类和其子类中使用 (后续讲解)
访问修饰符:真正的含义?
类 字段 方法
类的访问修饰符:
//public(这个类在任何地方都可以使用) internal
字段:private,public
方法:private ,public
6.变量,类和方法的命名法
骆驼命名法(camel):第一个单词的首字母小写,后续有含义的单词首字母大写。 变量
帕斯卡命名卡(pascal):每一个单词的首字母都大写。类名和方法名
7.new:代表含义:范子阳
Student stu=new Student();
01.创建对象
02.开辟空间
03.自动调用构造函数
8.字段和属性区别?
解析:01.属性不能保存数据,真正保存数据的是字段
02.属性是可有可无的,字段是必须的。
03.如果字段只想让类内部访问,那么设置成private,如果想找一个中间者,
在Main方法中访问到Student类中的私有字段,那么属性可以是一种选择。
希望:推荐大家以后书写类的时候,字段和属性成对出现。
.属性无非就是有get和set两个访问器组成
get:取值
set:赋值
9.自动属性
自动属性应用场景:当我们不需要做逻辑判定的时候可以使用自动属性
定义自动属性在后台会自动帮我们生成一个对应数据类型的私有字段
10.vs2012下写的项目如何在vs2010中打开
步骤一:找到sln文件,用记事本打开,将Format Version 12.00 改为11.00
步骤二:找到csprocj文件 ,用记事本打开,将<TargeFrameworkVersion>4.5</TargeFrameworkVersion>
改为4.0
步骤三:将App.Config文件中的如下节点中的内容换成4.0
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
</startup>
第二章 深入C#数据类型
1.封装
.封装又称信息隐藏,是指利用抽象数据类型(自定义类)将数据和数据的操作结合在一起,使其构成一个不可分割的独立实体,尽可能的隐藏内部的细节,只保留一些对外接口,使之于外部发生联系。
封装的优点
第一:重用;
第二:不必关心具体的实现; (方法)
第三:面向对象三大特征之一;
第四,具有安全性!
2.关于数组的那些事儿
如果我们定义一个数组,并且赋值了
int[] nums={1,2};
nums当中保存 的是堆中的地址:例如:0x001
nums[0]:访问的是堆中的内容
3.值类型(在栈上存储真实的值)和引用类型(堆和栈上都要分配空间)
值类型:
Short int long
Float
Double
Boolean
Char
Byte
C# 垃圾回收器回收器
Java 垃圾回收器回收器
二代
三代
四代
Student stu=new Student();
4.结构体
/*01.结构体不用new,就可以直接对其属性赋值
*02.结构体中可以有字段,属性和方法
*03.结构体是值类型,类是引用类型
*04.在结构体中不能给字段赋初值,但是类中可以.
*05.结构体中没有默认构造函数,但类中有默认构造函数
*/
所有数据类型的父亲都是Object
所有的值类型直接的父亲是ValueType,爷爷是Object
5.构造函数
默认如果定义了一个类,系统会自动的生成一个和该类名称相同,并且没有返回值类型,甚至连Void都没有的方法,该方法就称为构造函数!
Student stu=new Student();
注意问题:值类型的直接父类都是ValueType,而ValueType又继承自Object
特殊的值类型:枚举和结构体
特殊的引用类型:数组和接口
6.装箱和拆箱
由于装箱和拆箱对系统性能损耗很大,所以在真实的开发中我们尽量避免装箱和拆箱的操作。
C#编程指南(c#权威)
Object:是引用类型,并且是所有数据类型(值类型,引用类型)的父类
面试题:
int number=3; 值类型的直接父类:ValueType,ValueType的父亲是Object
Console.WriteLine(number.ToString());
结论:没有装箱
//ToString() Object提供的,所以没有装箱。
什么时候应该装箱,什么时候应该拆箱?
解析:由于装箱和拆箱过程都要损耗系统的性能,所以在开发中应该尽量避免装箱和拆箱。
7.值类型传递和引用类型传递
方法的参数是值类型和引用类型
注意:值传递和引用传递判定依据是有没有ref关键字
结论:
01.如果方法的参数类型本身就是引用类型,那么对参数值的修改会永久保存
例如:public void TP(SE se)
{
se.Count++;//真正的修改se对象的Count值
}
02.如果方法的参数类型本身是值类型,又没有ref修饰,那么对参数值的修改,不会永久保存()
03.如果方法的参数类型本身是值类型,但是有ref修饰,那么对象参数值的修改,也会永久保存。
值类型传递 :不带ref的参数传递 SE se
引用类型传递:带ref的参数传递
Windows Live Writer
经典练习 经理评分
思路分析:
*先准备一个SE类
* 准备一个对象数组,长度为3
* 写一个方法初始化集合的3项
* 如何将数组中的数据(肉眼看不到的数据)转换成界面上的ListView中的数据(肉眼能见到的数据)
值类型引用类型
Heap(堆) 栈(Stack) 队列
12K
3.面试题:
int number=3;
Console.WriteLine(number.ToString());
结论:没有装箱
四类八种类型
StringBuilder和StringBuffer
第三章 使用集合组织相关数据(终极内存数据容器)
一、集合概念引入
集合:某些指定的对象(SE)集中在一起就是集合
如下是一个Hello Kitty的集合
数组:可以存储相同数据类型的一堆数据的容器
二、第一个集合ArrayList的使用
★1.引子:
用ArrayList进行赋值的时候,需要使用Add()
但是对集合中元素的修正可以使用下标,eg.list[0]=1给新值
但是在集合中元素个数为0的情况下,不能用Add()方法之外的其他手段给集合中添加元素
,原因因为_size是集合的一个属性, 真正存储元素个数为0的时候。_Size也是0.
int[] nums = { 1, 2, 3, 3, 4, 5 };
我想在2和3之间插入一个元素100
数组的局限性:由于给数组中添加元素,删除元素的时候,特别麻烦,所以我想找一个替代数组的工具,来帮我们实现数组所能实现的功能。集合应运而生
集合的优点:01.自动扩容 02.集合当中很多方法可以让我们更加便捷的来操作集合中数据。(必须掌握)
扩展:集合本质的讲解(面试可以聊,加分)
00.使用ArrayList首先需要引入命名空间
01集合动态扩容原理:如果集合中元素个数为0,并没有开辟空间
02.默认如果集合中出现了第一个元素,那么集合的大小4,如果放入第5个元素,那么会扩容成8
03.如果在小括号中首次定义的时候指定了集合的长度,那么以后扩容的方式
变成初次指定数字大小的2倍;如果没有指定长度,那么遵循01的规范
04.集合内部也是通过两个数组相互copy完成的,但是微软已经对其做了优化,我们不用关心效率问题
★2.集合原理截图
小结:
01.集合的概念
自动扩容:
Capcity和Count区别?
02.构造函数
概念:给类定义一个方法,方法名和类名相同,没有返回值,连void都不能有。
03.非泛型集合在使用前,一定要先导入命名空间。
04.命名空间
解析:作用:能使用该命名空间下所有的内容(类,方法)
保证在不同的命名空间下可以出现同名类 。
weilengdeyu.Download()
Weiredeyxue.UPLoad()
三、集合中元素操作(添加,遍历,删除、常见错误)
1.常见属性:
Capacity:集合占用空间
Count:集合存储元素个数
2.常用方法:
添加:int Add(Object value) //添加一个对象到集合的末尾
遍历:通过foreach遍历
删除:Remove()、RemoveAt()和Clear()
*:注意事项:如果删除了集合中的某一个元素,那么集合的索引会自动维护
Remove():删除内容
RemoveAt():通过索引删除
Clear():一次性移除集合中所有的元素
Contains():是否包含某个元素
3.常见错误:见PPT
写自己的组件:其实就是你在微软已有的组件上进行第二次封装。例如
保证在TextBox中只能输入数字。
比如说,现在TextBox内容你想要按照自己特定的格式打印。自己在TextBox动手脚,然后让他支持对应格式的打印。
--01.ArrayList
删除方法,包含,
02.命名空间
同名类便于区分,加快检索硬盘上某个类的速度
Using System.Collections
Using System.Collections.Generic; //泛型命名,默认导入
03.var :隐式类型推断
最后一个问题:
int num=5;
04.HashTable
第一个:删除
没有RemoveAt()
第二个:
三个方案:根据key拿到value
只能拿到value
DictionayEntry
Foreach( DictionayEntry item in table)
{
item.Value
//命名空间.类名
}
第三个:HashTable是一种无序的双列集合。
第四个:ContainsKey()
01.集合对于数组优点:
001.操作方便(新增,删除,查找方便)
002.自动扩容(刚开始可以不指定集合初始容量)
02.集合的实现原理
解析:集合在设计上还是使用数组实现的,只不过微软对两个相互copy的数组的执行效率进行了优化,所谓的自动扩容,无非是将新数组长度定义成旧数组长度的两倍后,再将新数组的前N项用旧数组的所有项填充而已。
四、集合初始化器,对象初始化器
ArrayList engineers = new ArrayList()
{
new SE(){Name = "周星星",Age = 26,
Gender = Gender.male,ID = "000",Popularity = 10},
new SE(){Name = "王贱贱",Age = 22,
Gender = Gender.female,ID = "111",Popularity = 20},
new SE(){Name = "周姐姐",Age = 30,
Gender = Gender.male,ID = "222",Popularity = 20}
};
五、HashTable
Hashtable 通常称为哈希表
根据键(Key)可以查找到相应的值 (Value)
★1.HashTable注意事项
01.HashTable类型的集合只能用foreach循环遍历,因为没有索引
02.HashTable集合中元素是无序的(不会按照Add的顺序来展示元素内容)
03.HashTable中的key不能重复
04HashTabel没有RemoveAt()
★2.对HashTable遍历三种方案:
☆:第一种方式,遍历所有的keys,通过key的值获取value
☆:第二种方式:遍历所有的value集合
☆:第三种方式,同时遍历key和value
Eg:
foreach (DictionaryEntry item in table)
{
Console.WriteLine(item.Key + "value==" + item.Value);
六、泛型集合List<T>(理解difficult,写起来easy)
泛型:就是为了约束ArrayList中元素类型,而制定的一个新的集合类型,该类型只能加入同一类型的多个元素,标识符<T>,可以看成是一个占位符,泛型是将运行时错误提前到了编译时
七、泛型集合Dictionary<K,V>
Dictionary<string,Person> dic=new Dictionary<string, Person>();
八、自定义泛型
九、.NET集合框架(集合扩展)
Queue(队列):
Queue与Stack类似,主要区别是Queue类以先进先出(FIFO)的结构创建集合,即,元素进入集合的顺序与弹出顺序相同
队列图:
一、void Enqueue(object obj):将元素加入队列
二、object Dequeue():将队首元素从队列中删除
三、bool Contains(object obj):判断是否包含某元素
Stack(栈):
Stack:System.Collections.Stack类表示对象的简单的后进先出非泛型集合。
栈图:
常用方法:
泛型方法
//方法定义
static void Swap<T>(ref T lhs, ref T rhs){ T temp; temp = lhs; lhs = rhs; rhs = temp;}
//方法调用
public static void TestSwap(){ int a = 1; int b = 2; Swap<int>(ref a, ref b); System.Console.WriteLine(a + " " + b);}
第四章 深入类的方法
第四章 深入类的方法
1.构造函数
构造:方法名和类名相同,没有返回值
无参构造函数
带参构造函数
构造的生成策略:
注意:在C#中,当我们定义了一个类后,默认会生成一个与类名
同名的无参构造,但是如果我们自定义了任何一个带参构造,那么
系统不再帮助我们生成无参构造,在真实的开发中,推荐大家定义
两个构造函数,一个无参,一个带参。
2.方法重载
解析:在同一个类中,如果多个方法方法名称相同,但是参数列表(个数,顺序,类型)不同)的多个方法可以构成重载,和方法的返回值类型没有半毛钱关系
以下的两个方法可以构成方法重载
public void Say(string name,int age)
{
}
public void Say(int age,string name)
{
}
3.对象间的交互
已经不再是一个人单枪匹马打天下。协同工作。
Codeing
Testing
Designing :
开发文档+Db+coding+测试+实施+培训--维护 (多面手)
面向对象:
京东商城:电子商务网站。
什么架构
后台数据库:SQL Server 10.1 87
分层
和数据库打交道:小组
和业务打交道:小组
华丽的css,展示:第三个小组
无非是将内存中的数据用给一个Table承载出来
影院售票系统
Cinema:电影院
放映计划
放映厅(50
Seat
Ticket
放映计划
:Movie
枚举
时间
Movie
汽车租赁系统
网络电视精灵
体检套餐系统
员工打卡系统
UMLUnified Modeling Language (UML)又称统一建模语言或标准建模语言
1、用例图(use case diagram)
2、活动图(activity diagram)
3、静态结构图
4、顺序图(Sequence Diagram):时序图
5、交互纵览图(Interaction Overview Diagram)
6、通信图(Communication Diagram)
7、时间图(Timing Diagram)
8、状态机图(State Machine Diagram)
9、构件图(Component Diagram)
10、部署图(Deployment Diagram)
UML视频地址
http://www.umlonline.org/school/thread-466-1-1.html
点餐系统:时序图或者是顺序图
//客户:点餐(两个对象,一个是服务员,一个是菜单)
/*服务员:记录客人点餐
* 服务员:提交菜单给厨师
* 厨师:根据菜单做菜
* 厨师:提醒饭菜制作完毕
* 服务员:传菜(将做好的菜端给客户)
* 客户:用餐
*
* 中间的关系:通过订单关联在一起
* 订单内容(每张订单都应该有一个所有者,需要具有一个客户对象,还要有一个订单号,还要有订单内容,点餐内容)
*
*/
菜单类
属性:该菜单属于哪个顾客(client)
该菜单是哪个餐桌的(id)
顾客所点的菜(mealList)
顾客类
方法:点菜
Public void Order(Waitress waitress,Order order)
用餐
Eat
服务员类
记录客人点餐
GetOrder(Order order)
给厨师提交菜单
SendOrder(Chef chef)
传菜
TransCook()
厨师类
获取菜单
GetOrder(Order order)
厨师做菜
Cook()
提醒饭菜制作完毕
SendAlert(Waitress waitress)
第六章 继承
一、课程回顾
1.使用new实例化对象时,调用了什么?
解析:调用了构造函数
2.方法重载有哪些特点?
解析:在同一个类中,方法名相同该,参数里列表不同,和返回值类型无关
3.以下位于同一类中的两个方法是否属于方法重载?为什么?
public string Method1(string name){}
public void Method1(string address){}
解析:不可以,这两个方法就是同一个方法,在同一个类中无法共存。
二、预习问题
1.子类中调用父类成员的关键字是什么?
解析:base
2.重写父类方法使用什么关键字?
解析:override
3.继承有哪些特性?
解析:单根性
传递性
三、本章目标
1.理解继承的概念
2.熟练使用继承建立父类和子类
3.理解多态的概念
4.会重写虚方法实现多态
四、课程内容
1.当我们在编辑器中用到了Ctrl+C和Ctrl+V的时候,就证明我们的代码已经出现了冗余,这个时候需要考虑对
代码进行优化。
S2220班级问题:父类的哪些成员可以被继承?
解析:私有成员不能被继承,父类的构造
3.继承:在C#中,如果一个类后面通过冒号又跟了另外一个类,那么我们就称冒号前面的类
为子类,冒号后面的类为父类。这种书写类的方式放映出来的关系就称为类的继承关系。
子类:派生类
父类:基类或者超类
4.满足什么条件的类可以使用继承??
解析:满足is a关系的两个类可以使用继承。
案例:经理is a a 员工
程序员 is a 员工
学生 is a Person
5.如果new一个子类对象,那么有如下执行流程
01.先定位到子类对应构造函数,没有执行子类的方法体
02.转向了父类的无参构造函数,执行父类构造方法体
03.转向了子类的方法体继续执行。
点题的话:如果在子类构造中,没有使用base显示调用父类的构造,那么系统也会自动调用父类的无参构造
//01.base代表父类对象,如果base():调用父类的构造函数
//02.base代表的是方法调用,是不需要参数类型的
6.通过base调用父类构造函数注意点
解析:01.通过base调用父类构造函数只能书写在子类的构造后
02.通过base调用父类构造函数参数顺序和父类的构造参数一致
7.注意:方式一:new Student("张靓颖",20);
和方式二:new Student
{
Name="张靓颖",Age=20
}区别?
解析:最终都能实现对类中的属性赋值。
但是赋值的原理不同,
方式一:直接调用该类的带参构造赋值。
01.先通过无参构造创建出类的对象
02.对象名.属性名的方式赋值
8.访问修饰符
public:在任何位置都可以访问,甚至是跨程序集都可以访问。
private:只能当前类的花括号中访问。
protected:只能在当前类,当前类的子类,子类的子类(孙子类)中可以访问。
9.继承的传递性
如果一个类B继承自类A,而类C又继承类B,那么类C也可以访问到类A中非私有成员
10.继承的单根性 (C#不支持多继承 Java也不支持多继承)
在很久很久以前,有一个叫C++的家伙,他是支持多继承的语言,突然有一天,10个程序员用多继承,有9个都用错了,后续的Java和C#语言因此不再支持多继承。
在C#中,一个类只能有一个父类,C#和Java都不支持多继承。要想使用多继承,那么请您使用接口。。
11.遍历窗体上所有的控件,判断是不是文本框
foreach(Control c in this.Controls)
{
if(c is TextBox)
{
((TextBox)c).Text="";
}
}
is a 判断一个对象是否是某个类型。
12.继承的价值
01.模拟现实世界的关系
02.便于重用和扩展已彻底测试的代码,且无需修改
03.结构更清晰
13.多态
不同的对象对于同一个操作,做出的响应不同,那么这种情况在面向对象编程中就称为多态
使用多态的目的?
解析:使用多态就是为了统一调用
14.实现多态三种方式:
方式一:通过虚方法实现多态
实现多态的步骤
01.在父类中通过virtual关键字定义一个虚方法
02.在子类中通过override关键字对父类中的虚方法进行重写
03.调用的时候,调用的是子类的方法
目前为止,我们学了两种:
第一种:虚方法实现多态
通过在普通类Person中用Virtual关键字定义虚方法SayHello(),然后在子类Student中通过override关键字对父类的SayHello()方法进行重写。
如下:
Studnt类
Teacher类
在Main方法中调用
第七章 深入理解多态
1.里氏替换原则:在一个软件系统中,如果子类出现在父类出现的位置,而整个软件功能又没有影响,那么咱们称为里氏替换。
考试题:父类变量指向子类对象!!
2.里氏替换 是 设计原则的一种
七种设计原则 ,写成blogs。
3.Is 和as
Is 做类型判定, 要想进行父类对象 到子类 类型的转换,还得用 as
4.模拟员工回家-------->父类作为方法参数
Employee
--->GoHome(Traffic traffic)
Traffic ---父类
--->Bicycle (自行车)
--->Car
--->Tube
Program
--->Main
5.大话设计模式
简单工厂
单例
23种设计模式
两种方式实现多态:
普通类+ 虚方法
抽象类+抽象方法
市面上所有教程 都会明确指出一个观点 :抽象类不能实例化 。
潜台词:不能直接使用如下代码实例化
Animal animal=new Animal();//编译器报错
间接的通过子类构造,隐式 调用 父类构造的形态 来变相的在内存中 产生一个你肉眼不可见的对象。但是不幸的是 ,作为程序员的我们,无法拿到抽象类对象的引用(也就是栈上的变量名)。
7.接口 -------用接口实现多态
面试题
重载和重写的区别?
解析:方法重载在同一个类中,
方法重写在两个类中,
第七章内容总结:
1,实现面向对象的多态性有哪几种方法?
总共有3种,第一种,虚方法实现多态, 第二种:抽象方法实现多态 第三种:接口实现多态
目前为止,我们学了两种:
第一种:虚方法实现多态
通过在普通类Person中用Virtual关键字定义虚方法SayHello(),然后在子类Student中通过override关键字对父类的SayHello()方法进行重写。
如下:
Student类
Teacher类
在Main方法中调用
第二种:抽象方法实现多态
通过在抽象类Birds中定义抽象方法Fly(),然后在子类【燕子】中对抽象方法Fly()进行重写实现多态,重写方式和虚方法一样,也是使用override关键字
Birds类:
燕子类:
喜鹊类:
在Main中调用:
2,抽象类可以被继承吗?
可以,不仅可以被普通类继承,也可以被抽象类继承
3,抽象方法可以有方法体吗?
不可以,连花括号都不能有
4,简述抽象方法和虚方法的区别?
课本上
课堂笔记:
//01.定义一个抽象类,用abstract 修饰
//02.抽象方法不能有方法体,甚至连{}都不能有
//03.抽象方法只能存在于抽象类中,但是抽象类中可以有非抽象方法
//04.抽象类不能实例化
//05.抽象类中抽象方法只是用来规定方法的形式(参数,返回值),约束子类方法的形式
//06.抽象类中的抽象成员必须在子类中全部实现,除非子类也是抽象类
//07.子类实现抽象方法的快捷键,Ctrl+.(没有输入法情况下 )
//shift+alt+F10
//08.抽象类不能用static修饰,也不能是密封类(sealed):如果是static,抽象就无法被继承,也就失去了抽象类本身的意义
下次课内容:01.提问9点默写
02.封装,继承,多态自己扩展
深入理解多态
1.复习
01.在子类中访问父类成员的关键字是什么?
base
注意点:base()只能用在子类构造中
02.方法重载和方法重写的区别?
override:在不同的类中,一个方法用override关键字修饰,那么就对父类当中的同名方法进行了重写
重写的目的:就是为了实现多态,更进一步来说,就是为了统一调用
方法重载:overload:在同一个类中,多个方法名称相同,参数列表不同就可以构成重载,和返回值类型
有半毛钱关系
03.is关键字作用?
解析:判断类型是否兼容
2.预习检查
01.定义抽象类的关键字是什么?
解析:abstract
02.as关键字的作用是什么?
解析:as类型转换
03.抽象类中只能有抽象方法吗?
解析:可以。抽象方法只能出现在抽象类中。
3.本章目标
01.理解里氏替换原则
02.会使用父类类型作为参数
03.理解抽象类和抽象方法
04.理解虚方法和抽象方法的区别
4.里氏替换原则(7个原则)
概念:在一个软件系统中,子类可以替换父类出现的位置,而对软件的功能没有任何影响,就称为里氏替换原则。
5.is和as
is做类型判定,而as做类型转换,as进行类型转换和()强转效果是等价的。
6.用虚方法实现多态的步骤
子类重写父类的虚方法
两种方式
创建父类变量,实例化子类对象
把父类类型作为参数类型,该子类及子类对象作为参数传入
运行时,根据实际创建的对象决定执行哪个方法
7.什么是抽象类?
专业人士解析;如果在一个类前加上了abstract关键字,那么该类就称为抽象类
8.快速在子类中生成所有的抽象方法
方式一:在有输入法的情况下,使用Alt+Shift+F10
方式二;在无任何输入法的情况下,使用Ctrl+.
注意事项:01.必须无输入法状态
02.不能点击小键盘的点
9.如果一个类用sealed关键字修饰,那么该类就是密封类
特性:密封类不能被继承
10.如果以类用static修饰,那么该类就是静态类,在静态类中所有成员(成员变量和成员方法)都必须是静态的额
public static class SqlHelper
{
public static string name;
public static void Say()
{
}
}
注意点:
01.在静态方法中不能直接访问非静态的方法或者变量
如果要在静态方法中,访问非静态成员,那么要通过对象名.方法名访问。
11.面向接口编程
第八章 网络电视精灵
// 获取和设置当前目录(该进程从中启动的目录)的完全限定目录。
System.Environment.CurrentDirectory
01.什么是设计模式
* 解析:针对特定问题而提出特定的解决方案
能力:最少写
简单工厂不算23种设计模式中的一种,
工厂
抽象工厂
* 2.常用的设计模式总共有23种,今天的《简单工厂设计模式》和《单例设计模式》
3.设计模式参考书籍<大话设计模式> 、《设计模式之禅》和 <GOF>
假如我今天过生日,我想订一个Pizza(比萨饼),我想打电话订。我只要有一个生产Pizza的工厂。
奶酪pIzza
培根Pizza
02.简单工厂图解
.单例模式
在某些特殊的场合中,我们需要在内存中只驻留某个类的一个对象,KTV点歌系统,播放窗体只需要有一个。
1.ASP.NET和JSP的关系 ASP.NET 和JSP都是用来开发动态网站的技术,只不过ASP.NET是通过c#语言来操作的, 而JSP是通过Java语言来操作的。 04.为什么学习XML? 01.跨平台(操作系统),就是在windowns操作系统和Linux操作系统上均可以被解析 02.跨开发语言 03.超市管理系统 一家店 Access(文件型数据库) 每天看一下每个门市销售业绩 SQL Server数据库 Oralce 先将Access中的数据表导出到Excel文件 然后将Excel文件中的数据导入到Sql Server数据库 04.Java中实现企业级应用缺少了配置文件,那么灵活性就不复存在。 05.RSS订阅本质上就是一个XML文件 05.什么是XML? 解析:XML:Extensible Markup Language(可扩展标记语言) HTML:HyperLink Text Markup Language(超文本标记语言) xml文件和html文件的区别? 解析:01.xml严格区分大小写,html不区分 02.xml不是编译语言,xml和html都是解释型语言 03.html语言负责显示数据,而Xml文件就是专门用来存储数据 4.GB2312和GBK可以看成是等价的,都可以支持中文。 如果我们在书写xml文件的时候,如果自己用的encoding="utf-8"出现问题, 那么试着切成gb2312 06.xml书写注意点 1.xml文件严格区分大小写 07.解析xml文件 解析:01.做一个xml文档 02.copy到debug目录下 03.创建一个XmlDocument对象 Ctrl+.导入命名空间 04.调用doc.Load(“路径”) 05.拿到根节点 XmlNode root=doc.DocumentElement; 06.用foreach来获取子节点内容 08.问题记录 01.Load(string filename):绝对路径:"D:\123\Singer.xml" 02.item.Name指定的是<内容> ,item.InnerText指的是<>内容</> 09.TreeView控件 01.如何获取选中的节点?? 解析:TreeNode tn= tvList.SelectedNode; 02.如何移除某一个选中的节点? 解析:TreeNode tn= tvList.SelectedNode; tn.Remove(); 03.Tag:属性,以后编程的时候,思路可以向Tag偏移。 Tag:Tag属性是微软提供给编程人员的一个编程接口,通过它可以轻松的实现某些功能。 04.Level深度 10.网络电视精灵 业务需求:市场上有很多网络电视软件:PPS,PPTV,PPLive,风行,暴风 所以我们来开发一款自己的网络电视软件! 所用技术: 01.C/S架构,数据存储在XML文件中 02.简单工厂模式 03.继承和多态 04.解析XML文档技术 05.深入剖析内存中数据的走向 06.TreeView控件的使用 核心:通过该项目,大家应该对业务流程有一个整体把控。对继承和多态有深入的了解 |
这篇文章的目的主要为了后续工作的使用,在这里对S2深入.NET平台和C#编程中贯穿案例《网络电视精灵》的部分实现代码进行思路剖析。 一、项目框架的搭建: 我们都知道开发一个项目之前,应该对项目的整体框架进行搭建。或者专业一点称为详细设计。解析来我们就来看下网络电视精灵的大致结构,当然后续的功能可能还需要加入其它类。 思路分析: 1.创建对应的类 TvProgram:节目类 该类主要负责定义节目的属性,为后续从xml文件中读取的内容提供存放位置。 ChannelBase:频道基类 TypeAChannel:A类频道 TypeBChannel:B类频道 ChannelFactory:工厂类 上述四个类主要控制频道信息 ChannelManager:频道管理类 该类主要作用实质上减轻窗体中的代码量。相当于程序的工具类。 2013年8月18日 任务;加载所有的频道信息,绑定到界面的TreeView上 核心思路: 1.首先在频道管理类ChannelManager中写一个加载所有频道方法LoadAllChannel; 该方法作用读取FullChannels.xml文件,并且将读取到的内容赋值给ChannelBase 对象。关键的问题就转化成了如何创建一个ChannelBase对象。我们都知道ChannelBase本身是一个抽象类,无法创建实例。由此,我们想到可以通过其子类来创建对象。由于不同子类实例化需要多次new,我们单独写了一个工厂类(ChannelFafactory),来创建子类实例,但是该子类实例存储在父类变量中。赋值完成后,我们需要将频道对象添加到字典中。那么 LoadAllChannel方法结束后,字典中就有了XML文档中的数据。也就是我们实现了将 本地硬盘上的xml文件中的数据读取到了内存中的一个字典集合中。 2.将集合中的数据绑定到TreeView中 将字典集合中的数据通过Foreach拆解,每循环一项,都创建一个TreeNode对象。 并且将集合中的属性赋值给节点对应的属性。然后将拼接处的节点添加到TreeView上 。这里需要注意的是,如何找到TreeView控件中的【所有电视台】这个节点,因为 我们需要在该节点上添加频道名称。代码如下: 2013年8月21日 扩展:DGV绑定List<T> List<T> list=new List<T>(); dgv.DataSource=new BindingList<T>(list); 任务:1.将频道节目单填充到DataGridView中 2.实现TreeView的右键菜单功能(能添加电台和删除电台) 3.右键菜单控制 核心思路: 将频道节目单填充到DataGridView中 1.在对应的频道子类中书写Fetch方法,解析对应的频道xml文件,然后将xml文件中的数据读取到 public List<TvProgram> TvList { get; set; }中。 2.将TvList中的数据绑定到DataGridView上 实现TreeView的右键菜单功能(能添加电台和删除电台) 核心思路: 1.添加电台 其实我们在做的事情就是先获取所有电台的某一个电台(北京电视台),然后通过 Tag属性拿到该电台对应的属性,将拆解出来的属性赋值给我的电台下的某一个 节点,由于节点不存在,所以我们要构造出一个节点。然后赋值,赋值完成后,我们就将构造出来的 节点添加到我的电台下就OK。 当然,上面的操作仅仅是界面上新增电台的一个假象。程序再次运行时,我们添加的电台并没有保存。所以我们要将选中的电台添加到我的电台(由于我喜欢的电台可能有多个,所以我们定义了一个集合。)集合中。因为我们大家都知道集合中的数据时存储在内存中的,所以我们要向程序下次运行时,显示出我们添加的电台,那么就必须将集合中的数据永久保存。当然我们知道,永久保存数据的方法有很多,在这里我们采取的是使用txt文件的方式,所以我们书写了一个方法来帮我们完成这项工作,sw.WriteLine(“End”)主要为了方便后面对文本文件的读取 归结起来有3点: 01.在TreeView中添加节点 02.向集合中添加节点 03.将集合中数据写入文本文件 删除电台思路与这个差不多!就不赘述了。 右键菜单控制 核心思路:通过Visible属性控制右键菜单的显示和隐藏 |
网络电视精灵后续思路
1.点击TreeView上某个电视台节点后,显示该频道下所有的节目单,
将节目单内容填充到DataGridView控件中。
思路分析:既然TypeAChannel:ChannelBase对应的北京电视台,那么我们需要找到保存
北京电视台中所有节目的xml文件,然后接续该xml文件,每一个<TvProgram>
节点都是一个节目单对象。我只需要将解析出的内容加载到集合中。集合中就存储了
一系列TvProgram对象,我只需要将该集合绑定到DataGridView上就OK了。
DgvList.DataSource=list;
注意:在调用Fetch方法之前要清空下集合中的数据
2.可以将所有电视台下的某个频道添加到【我的电视台】下
思路分析:
第一步:将【所有电台】下选中的频道加入到【我的电视台下】(假象:内存中操作,程序退出后,数据不保存)
第二步:IO操作。将选中的节点添加到【我喜欢的电台】集合中,在ChannelManager类中通过
SaveToTxt()方法将集合中的数据写入到本地的文本文件中 ,并规定文件每行的保存格式。
TypeA|北京电视台|files/北京电视台.xml,,其中|只是为了到时候读取文本文件时可以将每一行内容
由字符串转换成对应的属性值。
第三步:01.将文本文件中内容重新赋值给集合。
每读取一行,就是一个ChannelBase对象,然后将该ChannelBase对象
添加到集合中。
02.集合中有了数据后,再下一次用户打开应用程序的时候,就将集合中的每一项构造成一个TreeNode节点。
然后将该节点作为【我的电视台】下的子节点存在。
//创建一个文件
using System.IO;
FileStream fs=new FileStream("D:\\123.txt",FileMode.Create);
//买一只钢笔
StreamWritter sw=new StreamWritter(fs);
//真正写入内容
sw.Write("我喜欢C#课程");
//关闭写入器
sw.Flush();
sw.Close();
fs.Close();
//判断文件是否存在
if(!File.Exists("E:\\123.txt"))
{
//不存在的时候copy
File.Copy("D:\\123.txt","E:\\123.txt");
}
//读取
FileStream fs=new FileStream("E:\\123.txt",FileMode.Open);
StreamReader sr=new StreamReader(fs,Encoding.Default);
string str=sr.ReadToEnd();
Console.WriteLine(str);
sr.Close();
fs.Close();
第九章 文件操作
bool System.Boolean
4Byte 32bit布尔型变量 逻辑值,true或者false,默认值为false
byte System.Byte
1Byte 8bit无符号整数无符号的字节,所存储的值的范围是0~255,默认值为0
sbyte System.SByte 1Byte
8bit有符号整数带符号的字节,所存储的值的范围是-128~127,默认值为0
char System.Char
2Byte 16bit 无符号Unicode字符,默认值为’\0’
decimal System.Decimal
16Byte 128bit十进制数不遵守四舍五入规则的十进制数,28个有效数字,通常用于财务方面的计算,默认值为0.0m
double System.Double
8Byte 64bit双精度的浮点类型,默认值为0.0d
float System.Single
4Byte 32bit单精度的浮点类型,默认值为0.0f
int System.Int32
4Byte 32bit有符号整数,默认值为0
uint System.UInt32
4Byte 32bit无符号整数,默认值为0
long System.Int64
8Byte 64bit有符号整数,默认值为0
ulong System.UInt64
8Byte 64bit无符号整数,默认值为0
object System.Object
指向类实例的引用,默认值为null
short System.Int16
2Byte 16bit有符号整数,默认值为0
ushort System.UInt16
2Byte 16bit无符号整数,默认值为0
string System.String
指向字符串对象的引用,默认值为null
持久化:
是将程序数据在持久状态和瞬时状态间转换的机制。通俗的讲,就是瞬时数据(比如内存中的数据,是不能永久保存的)持久化为持久数据(比如持久化至数据库中,能够长久保存)。
02.如何将程序中的数据持久化?
解析:我只要将内存中的数据保存成硬盘上的文件。Xml jpg mp3
03.一个经典作业?
解析:如何读取大文本文件??优良解决方案
04.通过几个类来实现文件的读写
FileStream fs=new FileStream();//创建出一个文件流
稍微低级类,高级类。让FileStream和StreamReader()
没有读取器的情况下,也可以文件的读取操作
01.文件操作相关
1.必须引入命名空间
2.FileMode枚举
Create:创建一个新文件,如果文件存在,覆盖原有内容
Open:指定打开现有文件
CreateNew:新建一个文件,如果文件存在,会抛出异常 ,该属性一般不用
Append:打开现有文件追加
3.当调用Flush方法的时候才真正的将内存中的数据写入到硬盘中。
4.文件操作5个步骤,务必理解
01.创建一个文件流,本质:指定要往哪个文件中写入内容(或者说在硬盘的指定位置创建一个空的文件) 白话:买了一张白纸
02.创建一个写入(读取)器,并指定写入(读取)哪个文件,和硬盘上的文件产生关联。
白话:买了一支钢笔
03.开始真正的写入(读取)
白话:开始动笔写文章
04.关闭写入(读取器)
白话:停止编写文章,盖上钢笔冒
05.关闭流:
白话:将白纸折叠收藏
02.File和Directory
File常见方法:
Directory常见方法:
03.FileInfo和DirectoryInfo
1.IO操作
1.如果我们需要对硬盘上的目录(文件夹)或者文件进行操作,在C#中需要引入System.IO命名空间。
2.如何对文本文件进行读写???
解析:注意点:如果读取文件出现乱码情况,通过Encoding.Default或者是Encoding.UTF-8来解决,如果我们想使用GB2312方式可以使用Encoding.GetEncoding(“GB2312”);
3.File (文件) Directory(文件夹,目录)
File类和Directory类都是静态类,可以直接点出对应的方法。
FileInfo DirectoryInfo 非静态类,需要先创建对象,然后再来使用
什么时候使用File,什么时候使用FileInfo???
解析:一般如果对文件的多个属性进行操作的时候,就是用FileInfo,因为其效率高。一般判断硬盘上一个文件是否存在,直接使用File.Exitst()
04.序列化与反序列化
序列化是将对象状态转换为可保持或传输的格式的过程。与序列化相对的是反序列化,它将流转换为对象。这两个过程结合起来,可以轻松地存储和传输数据。
序列化注意事项:
01.如果自定义类需要被序列化,那么必须打上[Serializable]特性
02.必须保证可序列化类的所有属性也均可以序列化
03.必须保证可序列化类的父类也可以序列化
04,如果只序列化部分属性,不需要序列化的属性上可以打上[NonSerializable]特性