第一天
1.new关键字
(1) 创建对象
(2) 隐藏从父类那里继承过来的成员
2.访问修饰符
public: 公开的,公共的。
private:私有的,只能在当前类的内部访问,类中的成员,
如果不加访问修饰符,默认就是private。
protected:受保护的,可以在当前类的内部访问,也可以在该类的子类中访问。
internal: 在当前项目中都可以访问, internal于public的区别就是一个限制在项目里,另一个不是。
protected internal:能够修饰类的访问修饰符只有两个,internal和public。
3.常用的关键字
this //当前类对象
base //父类构造函数
new //1.创建对象 2.隐藏父类成员
virtual //标记一个方法是虚方法
abstract //抽象的
override //重写
interface //接口
partial //不分类
sealed //密封类
return //1.在方法中返回要返回的指 2.立即结束本次方法
break //跳出当前循环
continue //结束本次循环,回到循环条件进行判断
static //静态的
struct //结构
enum //枚举
const //常量
Partial部分类
Sealed 密封类
(它可以继承于别人,别人不能继承于它)
- 模拟移动硬盘,U盘,MP3等移动设备插到电脑上进行读写数据
/// <summary>
/// 抽象的移动存储设备父类
/// </summary>
public abstract class MobileStorage
{
public abstract void Read();
public abstract void Write();
}
public class MobileDisk : MobileStorage
{
public override void Read()
{
Console.WriteLine("移动硬盘在读取数据");
}
public override void Write()
{
Console.WriteLine("移动硬盘在写入数据");
}
}
public class UDisk : MobileStorage
{
public override void Read()
{
Console.WriteLine("u盘在读取数据");
}
public override void Write()
{
Console.WriteLine("U盘在写入数据");
}
}
public class Mp3 : MobileStorage
{
public void PlayMusic()
{
Console.WriteLine("Mp3可以自己播放音乐");
}
public override void Read()
{
Console.WriteLine("Mp3读取数据");
}
public override void Write()
{
Console.WriteLine("Mp3在写入数据");
}
}
public class Computer
{
public MobileStorage MS
{
get;
set;
}
public void CPURead()
{
this.MS.Read();
}
public void CPUWrite()
{
this.MS.Write();
}
}
static void Main(string[] args)
{
MobileDisk md = new MobileDisk();
Mp3 mo3 = new Mp3();
UDisk u = new UDisk();
Computer CPU = new Computer();
CPU.MS = md;
CPU.CPURead();
CPU.CPUWrite();
Console.ReadKey();
}
虚方法,抽象方法
关于虚方法需要注意的几点:
- 父类中如果有方法需要让子类重写,则可以将该方法标记为virtual
- 虚方法在父类中必须有实现,而且是空实现。(有大括号,没有代码)
- 虚方法子类可以重写(override),也可以补充些
关于抽象方法注意的几点:
1. 需要用abstract关键字标记
2. 抽象方法不能有任何方法实现
3. 抽象成员必须包含在抽象类中。
4. 由于抽象成员没有任何实现,所以子类必须将抽象成员重写。
5. 抽象类不能实例化
抽象类的作用,抽象类的作用就是为了让子类继承。
6. 抽象类中可以包括抽象成员,可以包括有具体代码的成员。
7. 还有抽象方法不能用static修饰.
8. class Program
9. {
10. static void Main(string[] args)
11. {
12. }
13. }
14.
15. public abstract class Person
16. {
17.
18. private string _name;
19.
20. public string Name { get => _name; set => _name = value; }
21.
22.
23. public Person(string name)
24. {
25. this.Name = name;
26. }
27.
28. public Person()
29. {
30.
31. }
32.
33. public virtual void SayHello()
34. {
35.
36. }
37.
38. public abstract double Test(string name);
39.
40. // public abstract void Test();
41.
42.
43. }
44.
45. public class Student:Person
46. {
47.
48. public override double Test(string name)
49. {
50. return 12;
51. }
52.
53.
54. public void SayHello()
55. {
56.
57. }
58.
59. }
60.
接口
鸟和飞机都会飞,但是他们不能提取出一个父类来,所以这时候引入了接口 IFlayable
public interface IFlyable
{
void Fly();
}
- 接口中只能包含方法(属性、事件、索引器也都是方法)
- 接口中的成员都不能有任何实现
- 接口不能被实例化
- 接口中的成员不能有任何访问修饰符(默认为public)
- 实现接口的子类必须将接口中的所有成员全部实现
- 子类实现接口的方法时不需要任何关键字,直接实现即可。
- 接口存在的意义就是为了多态。
四个字形容接口——光说不做
*接口可以普通的实现或显式的实现。
显式实现是为了解决接口的重名问题。
面向对象复习结束:
虚方法实例
class Program
{
static void Main(string[] args)
{
//作业:员工类、部门经理类、程序员类
//部门经理也是员工,所以要继承自员工类。员工有上班打卡的方法,用类来模拟
Employee emp = new Programmer();
emp.Daka();
Console.ReadKey();
}
}
public class Employee
{
public virtual void Daka()
{
Console.WriteLine("员工九点打卡");
}
}
public class Manager : Employee
{
public override void Daka()
{
Console.WriteLine("经理十一点打卡");
}
}
public class Programmer : Employee
{
public override void Daka()
{
Console.WriteLine("程序员九点打卡");
}
}
抽象类实例:
class Program
{
static void Main(string[] args)
{
//作业:动物Animal 都有吃Eat和Bark的方法,狗Dog和猫Cat叫的方法不一样
//父类中没有默认的实现锁考虑用抽象方法
Animal a = new Cat();
a.Bark();
a.Eat();
Console.ReadKey();
}
}
public abstract class Animal
{
public abstract void Eat();
public abstract void Bark();
}
public class Cat : Animal
{
public override void Eat()
{
Console.WriteLine("猫咪舔着吃");
}
public override void Bark()
{
Console.WriteLine("猫咪喵喵叫");
}
}
public class Dog : Animal
{
public override void Bark()
{
Console.WriteLine("狗狗汪汪叫");
}
public override void Eat()
{
Console.WriteLine("狗狗咬着吃");
}
}
接口实例:
class Program
{
static void Main(string[] args)
{
//作业:鸟-麻雀,鸵鸟
//企鹅,鹦鹉
//鸟能飞,鸵鸟,企鹅不能。。。你怎么办
IFlyable fly = new MaQue();
fly.Fly();
Console.ReadKey();
}
}
public interface IFlyable
{
void Fly();
}
public class Bird
{
public double Wings
{
get;
set;
}
public void SayHello()
{
Console.WriteLine("我是小鸟");
}
}
public class MaQue : Bird, IFlyable
{
public void Fly()
{
Console.WriteLine("麻雀会飞");
}
}
public class TuoNiao : Bird
{
}
public class QQ : Bird
{
}
public class YingWu : Bird, IFlyable
{
public void Fly()
{
Console.WriteLine("鹦鹉会飞");
}
}
字符串复习
学习.net就是学习它的无数个类库怎么用
字符串的不可变性
4.字符串
1)字符串的不可变性
2)字符串可以看作是char类型的只读数组
方法:
IsNullOrEmpty
ToCharArray()
ToLower()
ToUpper()
Equals()
Contains
是否包含
IndexOf
如果没有返回-1
LastIndexOf
找最后一次,没有返回-1
Substring()
从下标为x的位置开始,截取y个
Split()
分割字符串
Join()
Replace()
Trim();
Length();
**集合里没有Length,集合里面是Count**
练习1.接收用户字符串,相反输出
方法1:
str = “abc”;
str.reverse();
方法2:
//课上练习2:接受用户输入的一句英文,将其中的单词以反序输出
string str = “I Love You”
string[] strNew = str.Split(new char[]{‘ ‘},StringSplitOptions.RemoveEmptyEntri)
for()
string test = "程$晓$";
使用:string[] temp = test.Split(new string[] { "$" }, StringSplitOptions.RemoveEmptyEntries);
输出结果:数组长度为2
temp[0]="程" temp[1]="晓";
使用:string[] temp = test.Split(new string[] { "$" },
StringSplitOptions.None);或string[]
temp = test.Split('$');
输出结果:数组长度为3 temp[0]="程" temp[1]="晓" temp[2]="";
File
求一下最高最低和平均工资。
高效的StringBuilder
StringBuilder
集合复习
ArrayList
HashTable
List<T>
Dictionary<TKey,TValue>
装箱或者拆箱
装箱:就是将值类型转换为引用类型
拆箱:就是将引用类型转换为值类型
值类型: bool int double char struct enum decimal //栈
引用类型: string 数组 集合 interface object 自定义类 //堆
ref的作用就是把值传递改成引用传递。
拆箱或装箱的两种类型必须具有继承关系。
(把int转成string string转成int不会发生拆装箱)
static void Main(string[] args)
{
//案例:把分拣奇偶数的程序用泛型实现。int[] nums = {1,2,3,4,5,6,7,8,9};奇数在左边,偶数在右边。
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> listJi = new List<int>();
List<int> listOu = new List<int>();
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] % 2 == 0)
{
listOu.Add(nums[i]);
}
else
{
listJi.Add(nums[i]);
}
}
listJi.AddRange(listOu);
foreach (var item in listJi)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
static void Main(string[] args)
{
//练习1:将int数组中的奇数放到一个新的int数组中返回
//将数组中的奇数取出来放到一个集合中,最终将集合转换成数组。
int[] nums = { 1, 2, 3, 4, 5, 6, 7, 8, 9 };
List<int> listJi = new List<int>();
for (int i = 0; i < nums.Length; i++)
{
if (nums[i] % 2 != 0)
{
listJi.Add(nums[i]);
}
}
//集合转换成数组
int[] numsNew = listJi.ToArray();
foreach (var item in numsNew)
{
Console.WriteLine(item);
}
Console.ReadKey();
}
这里简单顺便介绍一下初始化器(对象初始化器和集合初始化器)
这里按后面的走
//练习:把123转换为:一二三。Dictionary<char,char>
//"1一 2二 3三 4四 5五 6六 7七 8八 9九"
//123 一二三
string str = "1一 2二 3三 4四 5五 6六 7七 8八 9九";
Dictionary<char, char> dic = new Dictionary<char, char>();
string[] strNew = str.Split(new char[] { ' ' }, StringSplitOptions.RemoveEmptyEntries);
for (int i = 0; i < strNew.Length; i++)
{
//1一 strNew[i][0] strNew[i][1]
dic.Add(strNew[i][0], strNew[i][1]);
}
Console.WriteLine("请输入阿拉伯数字");
string input = Console.ReadLine();
for (int i = 0; i < input.Length; i++)
{
if (dic.ContainsKey(input[i]))
{
Console.Write(dic[input[i]]);
}
else
{
Console.Write(input[i]);
}
}
Console.ReadKey();
//练习:计算字符串中每种字符出现的次数(面试题)。 "Welcome to ChinaWorld";
string s = "Welcome to Chinaworld";
Dictionary<char, int> dic = new Dictionary<char, int>();
//遍历s
for (int i = 0; i < s.Length; i++)
{
if (s[i] == ' ')
{
continue;
}
if (dic.ContainsKey(s[i]))
{
dic[s[i]]++;
}
else
{
dic[s[i]] = 1;
}
}
foreach (KeyValuePair<char,int> kv in dic)
{
Console.WriteLine("字母{0}出现了{1}次", kv.Key, kv.Value);
}
Console.ReadKey();
//案例:两个(List)集合{"a","b","c","d","e"}和{"d","e","f","g","h"}、
List<string> listOne = new List<string>() { "a","b","c","d","e" };
List<string> listTwo = new List<string>() { "d", "e", "f", "g", "h" };
for (int i = 0; i < listTwo.Count; i++)
{
if (listOne.Contains(listTwo[i]))
{
listOne.Add(listTwo[i]);
}
}
foreach (var item in listOne)
{
Console.WriteLine(item);
}
Console.ReadKey();
静态类
结构和类的区别
class Program
{
static void Main(string[] args)
{
//类型
//结构:值类型 在内存的栈上
//类:引用类型 在内存的堆上
//声明的语法:class struct
//在类中,构造函数里,既可以给字段赋值,也可以给属性赋值。构造函数是可以重载的
//但是,在结构的构造函数中,必须只能给字段赋值
//在结构的构造函数当中,我们需要给全部的字段赋值,而不能去选择的给字段赋值
//调用:
PersonClass pc = new PersonClass();
//1.在堆开辟空间 2.在堆创建对象 3.调用构造函数初始化
//结构是否可以new?
PersonStruct ps = new PersonStruct();
ps.M2();
PersonStruct.M1();
Console.ReadKey();
//在栈中开辟空间 结构new 调用结构的构造函数
//结构和类的构造函数:
//相同点:不管是结构还是类,本身都会有一个默认的无参数的构造函数
//不同点:当你在类中写了一个新的构造函数之后,那个默认的无参数的构造函数都被干掉了
//但是,在结构当中,如果你写了一个新的构造函数,那么那么默认的无参数的构造函数怡然存在
//
//如果只是单纯的存储数据,我们推荐使用结构。
//如果我们想要使用面向对象的思想来开发程序,我们推荐使用Class。
//结构并不具备面向对象的特征
}
}
public class PersonClass
{
//字段、属性、方法、构造函数
}
public struct PersonStruct
{
private string _name;
private int _age;
private char _gender;
public string Name { get => _name; set => _name = value; }
public char Gender { get => _gender; set => _gender = value; }
public int Age1 { get => _age; set => _age = value; }
public static void M1()
{
Console.WriteLine("我是结构中的静态方法");
}
public void M2()
{
Console.WriteLine("我是结构的非静态方法");
}
public PersonStruct(string name, int age, char gender)
{
//this.Name = name;
//this.Age = age;
//this.Gender = gender;
this._name = name;
this._age = age;
this._gender = gender;
}
//public PersonStruct(string name)
//{
// this._name = name;
//}
}