目录
- 课程一、C#基础
- 课程二、Timothy C#底层讲解
-
- 一、类成员
-
- 0常量
- 1字段
- 2属性
- 3索引器
- 5方法
-
- 5.1值参数(创建副本,方法内对值的操作,不会影响原来变量的值)
- 5.2引用参数(传的是地址,方法内对值的操作,出了方法后原来的值也被修改)
- [5.3 输出参数(普通方法一次调用只产出一个返回值,但希望一次调用返回多个输出值,所以用输出参数)](#5.3 输出参数(普通方法一次调用只产出一个返回值,但希望一次调用返回多个输出值,所以用输出参数))
- [5.4 数组参数 parmas(可供函数输出多个值)](#5.4 数组参数 parmas(可供函数输出多个值))
- [5.5 具名参数(调用方法时,参数带有名字,位置随意)](#5.5 具名参数(调用方法时,参数带有名字,位置随意))
- [5.6 可选参数(方法定义声明时,有默认值)](#5.6 可选参数(方法定义声明时,有默认值))
- [5.7 扩展方法(this参数)](#5.7 扩展方法(this参数))
- 二、委托
-
- [1委托(c# Action,Func常规委托)](# Action,Func常规委托))
- [2委托声明 (delegate自定义委托)](#2委托声明 (delegate自定义委托))
- 3委托使用(把方法当做参数会给另一个方法:模板法,回调法)
- 4委托高级使用(多播委托\异步委托调用)
- 三、事件
- 四、类
- 五、接口、抽象类
- 六、反射、依赖注入
- 七、泛型(这里代码多练习)
- 八、核心代码汇总
课程一、C#基础
1.C#编译环境、基础语法
csharp
F12查看函数被引用的地方,ctrl +减号 返回
F10,debug时的一步步调试
alt+s左键 选几行中的某些字段
calculator.repoort() 加括号表示调用方法 calculator.repoort 表示方法名
csharp
1.查看变量类型
Debug.WriteLine(array3.GetType().ToString())
2.抛出异常
try
{
可能会出现异常的代码块;
}
//try和catch之间不能有其它的代码
catch
{
出现异常后要执行的代码块;
}
3.查看两变量或对象是否是一个值?
Console.WriteLine{"{0}",stu.GetHashCode()};
4.将文件中一个变量名统一修改成另外一个
对一个修改完后,按 ctrl+点 实现
5.类是典型的引用类型
6.Action action1 = new Action(stu1.dohomework); stu1.dohomework 是函数名
7.1.类中定义方法时,后面不用加; 只有执行的语句要加;2.stu1.dohomework()是方法的调用 stu1.dohomework 是函数名 public double Price { get; set; } Action action1 = new Action(stu1.dohomework); stu1.dohomework 是函数名
8.registerMonitor.get_Reg = get_reg_values; get_reg_values没有变量类型,没有括号表示方法,那么是委托
9.使用alt+enter对写的代码进行补充
10.//委托类型创建 为 order事件创建
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
private OrderEventHandler orderEventHandler;//委托字段,用来存储事件处理器
11.一个类可以继承单个类,一个类可以有多个接口,一个接口也可以继承多个接口
12. new 创建的是静态类型,typeof 拿到的是动态描述
c# 了解
1.net 运行平台上,运行vb,c#,c++语言(.net环境为vb,c#,c++封装了各种工具包) .net core跨平台开发(可运行win linux) 相当于java开发工具包jdk上,包含java运行环境(jre,jvm+java系统类库)和java工具
2.c#工具 visual studio 2019
关键字声明 class类 namespace int(申明整数变量)
//单行注释
/* */多选注释
// 放到类、方法前按下///进行注释
变量为小数1.123,系统将其认为是double 型, float a=1.123报错 double a=1.123正确
string s='"" 与s=null 区别:""""的字符串为空, null直接就是空,存字符串的地方都没有,只有string才可以=null,其他类型变量不可以
int x=2;
show(++x) ; x=3 前++先执行
show(x); x=3
string a=5;
show(a++); a=5 后++ 后执行
show(a); a=6
IF要一个个判断才能选择某个分支,switch直接进入那个分支
csharp
private void InitializeComponent()
{
MessageBox.Show("linyang");
int a = 2;
switch (a) //a可以为数字也可为string
{
case 1:
MessageBox.Show("1");
break;
case 2:
MessageBox.Show("2");
break;//必须要break
}
csharp
//for 循环直接循环 while 预设一个条件,当条件满足时进入循环, do {}while 先执行,达到条件退出
for (int a =2; a<4; a++)
{
MessageBox.Show(a.ToString());
};
int i = 1;
while (i <=3) {
MessageBox.Show((i++).ToString());
}
int b = 1;
do {
MessageBox.Show((b).ToString());
b++;
}
while (b < 4);
每次new就会开辟一个新地址,尽管内容一次,但不是同一个
csharp
//关键字 int,int[] 声明变量类型,new 创建数组
int q = 2;
int[] a = new int[6];
int[] b = new int[3] { 1,2,3};
int[] c = new int[] { 'a',2,3};
MessageBox.Show(c[0].ToString()); //输出97
csharp
/*无修饰时函数内部处理的是副本不影响原来的值
string want = "2222"; //want = "2222"
Sellhouse(want); //box显示1111
MessageBox.Show(want.ToString()); //box显示2222
*/
/*out修饰时,引用传递, 函数内部处理的是原地址,影响原来的值
string want = "2222"; //want = "2222"
Sellhouse1(out want); //box显示1111
MessageBox.Show(want.ToString()); //box显示1111
*/
/*ref修饰时,引用传递, 函数内部处理的是原地址,影响原来的值,与out不同,out使用函数中(Sellhouse1)必须要赋值否则报错
string want = "2222"; //want = "2222"
Sellhouse2(ref want); //box显示1111
MessageBox.Show(want.ToString()); //box显示1111
*/
}
public void Sellhouse(string want)
{
want = "1111";
MessageBox.Show(want.ToString());
}
public void Sellhouse1(out string want)
{
want = "1111"; //有out时必须要赋值,否则报错
MessageBox.Show(want.ToString());
}
public void Sellhouse2(ref string want)
{
want = "1111"; //有ref时,谁调用它必须赋初值,否则报错
MessageBox.Show(want.ToString());
}
类与方法
数组是连续的不能add,delete(new int[3])
集合(arraylist支持add,delete但是装箱拆箱耗时-由于存储变量类型不一致情况导致,
list泛型 list约束了只支持一种类型)
int[] a=new int[5]
Arraylist a=new Arraylist()
csharp
List<int> a = new List<int>( );
List<int> b = new List<int> { 1,2,2};
List<Person> p = new List<Person>();
a.Add(112);
a[0] = 4;
a.Insert(0, 3);
a.RemoveAt(0);
a.Remove(4);
a.Clear();
p.Add(new Person() { });
Dictionary<int, string> c = new Dictionary<int, string>();
Dictionary<int, string> d = new Dictionary<int, string> { //对象初始化器
{ 2,"333"},{4,"555"}
};
c.Add(1, "111");
c.Add(2, "222");
c.Add(3, "333");
string value = c[2];//通过键索引到值; "222"
bool f=c.Remove(1);//通过键删除那个值
csharp
int[] a = new int[] { 3,4,5};
foreach (int i in a)
{
MessageBox.Show(i.ToString());
}
List<int> b = new List<int> { 2,3,4};
foreach(int i in b)
{
MessageBox.Show(i.ToString());
}
Dictionary<string, string> c = new Dictionary<string, string>() { {"aa","aaaaa" },{"bb","bbbb" } };
foreach (KeyValuePair<string,string> i in c)
{
string key = i.Key;
string value = i.Value;
}
2.Winform-后续未学完
课程二、Timothy C#底层讲解
一、类成员
0常量
math.PI 就是常量 运算效率高,不用从内存中读
1字段
实例字段初始化时机:创建一个类时
静态字段初始化时机:这个程序被加载时,字段在声明时就初始化了,只初始化一次
2属性
1属性完整申明
csharp
// 在类中输入 propfull按两下tab自动生成
class person
{
private int age;
public int Age
{
get { return age; }
set {
if (value >= 0 && value <= 120)//这个value是微软特定设置在set下的,不用申明
{
age = value;
}
else
{
throw new Exception("age value has error11111");
}
}
}
}
//使用,使用private后
person p1 = new person();
p1.Age=100;
2属性简易申明,对字段没有保护措施
csharp
// 在类中输入 prop按两下tab自动生成
class person
{
public int MyProperty { get; set; }
}
3字段int age->方法对 get() ->属性Age{get;set}的推演
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
try
{
Student stu1 = new Student();
stu1.Age = 20;//使用private后,类调用属性只能get set方法
//stu1.Setage(20);
Student stu2 = new Student();
//stu2.Setage(20);
stu2.Age = 20;
Student stu3 = new Student();
//stu3.Setage(810);
stu3.Age = 210;
int avgage = (stu1.Age + stu2.Age + stu3.Age) / 3;
Console.WriteLine(avgage);
Console.Read();
}
catch(Exception ee)
{
Console.WriteLine(ee.Message);//"age value has error"打印到前台
Console.Read();
}
}
}
class Student
{
private int age;
public int Getage ()
{ return this.age;
}
public void Setage(int value)//属性可以对变量防护
{
if (value >= 0 && value <= 120) {
this.age = value;
}
else
{
throw new Exception("age value has error");
}
}
private int age;
public int Age
{
get { return this.age; }
set
{
if (value >= 0 && value <= 120)//这个value是微软特定设置在set下的,不用申明
{
this.age = value;
}
else
{
throw new Exception("age value has error11111");
}
}
}
}
}
3索引器
索引器用在集合中
csharp
//输入index 按两下TAB生成
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
try
{
Student stu = new Student();
var mathscore = stu["Math"];
Console.WriteLine(mathscore==null);
Console.Read();
}
catch(Exception ee)
{
Console.WriteLine(ee.Message);//"age value has error"打印到前台
Console.Read();
}
}
}
class Student
{
private Dictionary<string, int> score = new Dictionary<string, int>();
public int? this[string subject] //int?可空int型号 subject自己定义的成绩科目名为subject
{
get {
if (this.score.ContainsKey(subject))
{
return this.score[subject];
}
else
{
return null;
}
}
set { /* set the specified index to value here */
if (value.HasValue == false)
{
throw new Exception("score cannot be null");
}
if (this.score.ContainsKey(subject))
{
this.score[subject]=value.Value;//int?可空int型号
}
else
{
this.score.Add(subject, value.Value);
}
}
}
}
}
5方法
5.1值参数(创建副本,方法内对值的操作,不会影响原来变量的值)
引用类型,不创建新对象
5.2引用参数(传的是地址,方法内对值的操作,出了方法后原来的值也被修改)
引用参数在传入方法前必须有个明确的赋值,然后在方法中修改
5.3 输出参数(普通方法一次调用只产出一个返回值,但希望一次调用返回多个输出值,所以用输出参数)
讲解的时值先讲值 引用变化,再讲类引用变化
5.4 数组参数 parmas(可供函数输出多个值)
5.5 具名参数(调用方法时,参数带有名字,位置随意)
5.6 可选参数(方法定义声明时,有默认值)
5.7 扩展方法(this参数)
二、委托
1委托(c# Action,Func常规委托)
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);//Action: 方法是void,并且无参数
action.Invoke();//委托调用
action();//模仿c中函数指针的书写格式
calculator.Report();//直接调用方法名
//<第一个int为返回值, 第二三个int为函数输入>
Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);//Func :方法是有返回,有参数
Func<int, int, int> func2 = new Func<int, int, int>(calculator.Sub);
int x = 100;
int y = 200;
int z = 0;
z = func1.Invoke(x, y);//委托调用
Console.WriteLine(z);
z = func2.Invoke(x, y);
Console.WriteLine(z);
func1(x, y);//模仿c中函数指针的书写格式
}
}
class Calculator
{
public void Report() {
Console.WriteLine("i have 3 methods");
}
public int Add(int a,int b)
{
int result = a + b;
return result;
}
public int Sub(int a, int b)
{
int result = a - b;
return result;
}
}
}
2委托声明 (delegate自定义委托)
3委托使用(把方法当做参数会给另一个方法:模板法,回调法)
实现目的:方法中调用方法
现实中是无法操作的,所以采用模板方法+用委托类型参数封装的方法的方式来实现,委托相当于一个指针,可以指定任意方法,就可以实现方法调方法。
模板方法:方法中 输入 用委托类型参数封装的方法
回调方法:方法中 在调用 用委托类型参数封装的方法 时,有条件判断
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
ProdectFactory prodectFactory = new ProdectFactory();
WrapFactory wrapFactory = new WrapFactory();
//<第一个int为返回值, 第二三个int为函数输入>
// Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);//Func :方法是有返回,有参数
//1委托封装方法
//Product为委托的返回类型 ,func1为委托名 =new委托的返回值类型是Product,委托的函数名称=prodectFactory.MakePiza
Func<Product> func1 = new Func<Product>(prodectFactory.MakePiza);
Func<Product> func2 = new Func<Product>(prodectFactory.Makecar);
Logger logger = new Logger();
Action<Product> log = new Action<Product>(logger.Log);
//2调用模板方法,返回值为box1
Box box1=wrapFactory.WrapProduct(func1,log);
Box box2 = wrapFactory.WrapProduct(func2,log);
Console.WriteLine(box1.product.Name);
Console.WriteLine(box2.product.Name);
Console.Read();
}
class Logger
{
public void Log(Product product)
{
Console.WriteLine("Product '{0}' created at {1},price is {2}", product.Name, DateTime.UtcNow, product.Price);
}
}
class Product
{
public string Name { get; set; } //类属性是string
public double Price { get; set; }
}
class Box
{
public Product product { get; set; }//类属性是一个类
}
class WrapFactory
{
//WrapProduct 委托的模板方法,Box方法的返回值
//委托模板方法的输入是委托函数 Func<Product> getProduct
public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback)
{
Box box = new Box();
Product product = getProduct.Invoke();
if (product.Price > 50)
{
logCallback(product);
}
box.product=product;
return box;
}
}
class ProdectFactory
{
public Product MakePiza()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = 12;
return product;
}
public Product Makecar()
{
Product product = new Product();
product.Name = "car";
product.Price = 100;
return product;
}
}
}
}
4委托高级使用(多播委托\异步委托调用)
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Student stu1 = new Student() { id = 1, pencolor = ConsoleColor.Yellow };
Student stu2 = new Student() { id = 2, pencolor = ConsoleColor.Green };
Student stu3 = new Student() { id = 3, pencolor = ConsoleColor.Red };
/* 1.同步间接调用-使用委托
Action action1 = new Action(stu1.dohomework);
Action action2 = new Action(stu2.dohomework);
Action action3 = new Action(stu3.dohomework);
//action1.Invoke();//单播委托
// action2.Invoke();
//action3.Invoke();
//多播委托
action1 += action2;
action1 += action3;
action1.Invoke();*/
//------------------------------------------------------------
/*
// 2同步直接调用
stu1.dohomework();
stu2.dohomework();
stu3.dohomework();
//------------------------------------------------------------
// 3隐式异步调用
Action action1 = new Action(stu1.dohomework);
Action action2 = new Action(stu2.dohomework);
Action action3 = new Action(stu3.dohomework);
action1.BeginInvoke(null, null);//第一个null为执行完线程后的回调函数
action2.BeginInvoke(null, null);
action3.BeginInvoke(null, null);
//------------------------------------------------------------
// 4显式异步调用
Thread thread1 = new Thread(new ThreadStart(stu1.dohomework));
Thread thread2 = new Thread(new ThreadStart(stu2.dohomework));
Thread thread3 = new Thread(new ThreadStart(stu3.dohomework));
thread1.Start();
thread2.Start();
thread3.Start();*/
// 4显式异步调用
Task task1 = new Task(new Action(stu1.dohomework));
Task task2 = new Task(new Action(stu2.dohomework));
Task task3 = new Task(new Action(stu3.dohomework));
task1.Start();
task1.Start();
task1.Start();
for (int i=0; i < 5; i++)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.WriteLine("main thread{0}", i);
Thread.Sleep(1000);
Console.Read();
}
}
class Student
{
public int id { get; set; }
public ConsoleColor pencolor { get; set; }
public void dohomework()
{
for (int i =0; i <5;i++) {
Console.ForegroundColor = this.pencolor;
Console.WriteLine("student{0} doing homework {1} hours", this.id, i);
Thread.Sleep(1000);
}
}
}
}
}
三、事件
1事件定义
一个对象有事件,对象通过事件的发生来通知其他对象
程序员自己写的代码 订阅一个按钮,当按钮点击事件由客户触发时,那么代码就会对其进行响应。
用户操作下鼠标,就会执行一块程序,鼠标不用,那么这块程序就不执行。称这块程序为事件驱动程序。
2事件应用(5要素)
事件的拥有者决定事件是否发生
按钮的内部逻辑(按下松开),触发了自己的click事件,
click事件发生了就会告知相应的订阅者,
相应的订阅者就会产生相应的行为。
这个约定就是委托,事件建立在委托上
事件与响应方法是可以1对多,多对1
csharp
订阅的挂接方式
this.button.click+=this.buttoonclicked;
this.button.click+=new EventHandler(this.buttoonclicked);
this.button.click+=(object sender, EventArgs e)=>{ this.textBox.text='hah';}; //流行
this.button.click+=delegate(object sender, EventArgs e){ this.textBox.text='hah';}//匿名方法过时
事件与响应方法是可以1对多,多对1
csharp
//一星展示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Timer timer = new Timer(); // timer.Elapsed事件的拥有者Timer
timer.Interval = 1000;
Boy boy = new Boy(); //事件的订阅者
Girl girl = new Girl();
// 订阅者的处理器 +=表示订阅 拿方法订阅一个事件时,它们要遵守约定:约定就是委托类型
// timer.Elapsed的类型就是 public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);
// 所以使用alt+enter自动按照委托形式对boy.Action进行方法创建
timer.Elapsed += boy.Action; //timer.Elapsed 为事件,boy.Action为事件处理器
timer.Elapsed += girl.Action; //一个事件两个订阅者
timer.Start();
Console.ReadLine();
}
class Boy
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Jump");
}
}
class Girl
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("sing");
}
}
}
}
csharp
//三星展示
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Form form=new Form();//事件的拥有者
Controller controller = new Controller(form);//事件的响应者
form.ShowDialog();
}
class Controller
{
private Form form;
public Controller(Form form)
{
if (form != null)
{
this.form = form;
this.form.Click += this.Formclicked;//约定
}
}
private void Formclicked(object sender, EventArgs e)
{
this.form.Text = DateTime.Now.ToString();
}
}
}
}
csharp
//自己调自己,两星事件
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Myform myform = new Myform();
myform.Click += myform.Formclicked;
myform.ShowDialog();
}
class Myform : Form
{
internal void Formclicked(object sender, EventArgs e)
{
this.Text = DateTime.Now.ToString();
}
}
}
}
csharp
//三星:事件的拥有者是响应者的成员
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Myform myform = new Myform();
myform.ShowDialog();
}
}
class Myform : Form
{
private TextBox textBox;
private Button button;//form的字段成员,拥有者
public Myform()
{
this.textBox = new TextBox();
this.button = new Button();
this.Controls.Add(this.button);
this.Controls.Add(this.textBox);
this.button.Click += this.buttonCllicked; //form =响应者
this.button.Text = "sss";
}
private void buttonCllicked(object sender, EventArgs e)
{
this.textBox.Text = "hello world```````````````````````````";
}
}
}
3事件自定义
委托是事件的底层基础,事件是委托的上层建筑
csharp
//第三种
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
namespace ConsoleApp1
{
class Program
{
static void Main(string[] args)
{
Customer customer = new Customer(); //1事件拥有者
Waiter waiter = new Waiter();//2事件的响应者
customer.Order += waiter.Action;//事件 , 事件处理器 事件拥有者的内部逻辑触发了事件
customer.Action();//事件触发
customer.Paybill();
}
}
//事件的信息
public class OrderEventArgs:EventArgs
{
public string Dishname { get; set; }
public string Size { get; set; }
}
//委托类型创建 为 order事件创建
public delegate void OrderEventHandler(Customer customer, OrderEventArgs e);
public class Customer //1事件拥有者
{
private OrderEventHandler orderEventHandler;//委托字段,用来存储事件处理器
public event OrderEventHandler Order //2事件
{
add
{
this.orderEventHandler += value;
}
remove
{
this.orderEventHandler -= value;
}
}
public double Bill { get; set; }
public void Paybill ()
{
Console.WriteLine("i will pay ¥{0}", this.Bill);
}
public void Walk()
{
Console.WriteLine("walk into restaurant");
}
public void Sitdown()
{
Console.WriteLine("Sitdown");
}
public void Think()//事件触发
{
for (int i=0; i < 5; i++)
{
Console.WriteLine("let me thikn''''");
Thread.Sleep(1000);
}
if (this.orderEventHandler != null)//如果没人订阅这个事件,事件发生时会报错
{
OrderEventArgs e = new OrderEventArgs();
e.Dishname = "KONGBAO JIDING";
e.Size = "large";
this.orderEventHandler.Invoke(this, e);
}
}
public void Action()
{
Console.ReadLine();
this.Walk();
this.Sitdown();
this.Think();
}
}
public class Waiter
{
public void Action(Customer customer, OrderEventArgs e)
{
Console.WriteLine("i will serve you dish {0}", e.Dishname);
double price = 10;
switch (e.Size)
{
case "small":
price = price * 0.5;
break;
case "large":
price = price * 2;
break;
default:
break;
}
customer.Bill += price;
}
}
}
四、类
1构造器、析构器
2.类修饰符(public\internal\abstract)
类的继承
sealed修饰类后,这个类不能被当成基类使用
一个类只能有一个基类
子类的类访问级别不能超越基类
横向扩展对类成员的扩充,纵向扩展对类成员的重写
子类是对父类的全盘继承
类成员的访问级别 低于类的访问级别
类定义默认是public ;类是属性默认为private
public 一个solution的多个项目都可访问
internal 在一个项目中的多个类中访问
private 只在当前类中使用,就算继承也不能访问
protected 修饰的类成员,此类成员只能被继承的类所调用
3类的继承
五、接口、抽象类
(人--接口--手机)多个人可分别使用不同款式手机
面向对象设计基本原则,通过设计的规则,让代码更为规范
abstract抽象类:函数成员未被完全实现的类(无方法体),不能实例化,抽象类只能作为基类,为子类服务,子类进行重写
abstract抽象类 一方面是用于子类继承,第二方法抽象类父类变量引用子类实例,代查
concrete具体类
开闭原则:在设计类的时候,把那些固定不变的方法,属性进行封装,把来回变动的采用抽象类,抽象方法供子类使用
接口,抽象类,具体类
csharp
//耦合过多,car依赖于engine,engine出了问题 car也出问题,所以使用接口来解耦合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var engine = new Engine();
var car = new Car(engine);
car.Run(3);
Console.WriteLine(car.Speed);
Console.ReadKey();
}
}
class Engine
{
public int RPM { get; private set; }
public void Work(int gas)
{
this.RPM = 1000 * gas;
}
}
class Car
{
private Engine _engine;
public Car(Engine engine)
{
_engine = engine;
}
public int Speed { get; private set; }
public void Run(int gas)
{
_engine.Work(gas);
this.Speed = _engine.RPM / 100;
}
}
}
csharp
//用接口来解耦合
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var user = new phoneuser(new nokia());
var user1 = new phoneuser(new erision());
user.usephone();
Console.Read();
}
}
class phoneuser
{
private iphone _phone;
public phoneuser( iphone phone)
{
_phone = phone;
}
public void usephone()
{
_phone.dail();
_phone.pickup();
_phone.send();
_phone.receive();
}
}
interface iphone
{
void dail();
void pickup();
void send();
void receive();
}
class nokia : iphone
{
public void dail()
{
Console.WriteLine("dailing........");
}
public void pickup()
{
Console.WriteLine("pickup......");
}
public void receive()
{
Console.WriteLine("receiving.......");
}
public void send()
{
Console.WriteLine("sending......");
}
}
class erision : iphone
{
public void dail()
{
Console.WriteLine("dailing-------");
}
public void pickup()
{
Console.WriteLine("pickup---------");
}
public void receive()
{
Console.WriteLine("receiving-------");
}
public void send()
{
Console.WriteLine("sending--------");
}
}
}
csharp
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var fan = new deskfan(new powersupply());
Console.WriteLine(fan.work());
Console.Read();
}
interface ipowersupply
{
int getpower();//定义一个返回值为int 的方法,无方法体
}
class powersupply:ipowersupply
{
public int getpower()
{
return 100;
}
}
class deskfan
{
private ipowersupply _powersupply;//由耦合函数powersupply换成接口函数 ipowersupply
public deskfan(ipowersupply powersupply)//由耦合函数powersupply换成接口函数 ipowersupply
{
_powersupply = powersupply;
}
public string work()
{
int power = _powersupply.getpower();
if (power < 0) { return "wont work"; }
else if (power < 100) { return "slow"; }
else if (power < 200) { return "work fine"; }
else { return "warning"; }
}
}
}
}
六、反射、依赖注入
csharp
## 一个类多个可以多个接口,接口也可继承多个接口interface Itrank: IVehicle, Iweapon
class Program
{
static void Main(string[] args)
{
var driver = new Driver(new Car());
var driver1 = new Driver(new Truck());
var driver2 = new Driver(new lighttrank());
driver.Drive(); driver1.Drive(); driver2.Drive();
Console.ReadKey();
}
class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}
interface IVehicle
{
void Run();
}
class Car : IVehicle
{
public void Run()
{
Console.WriteLine("car is running");
}
}
class Truck : IVehicle
{
public void Run()
{
Console.WriteLine("Truck is running");
}
}
interface Iweapon
{
void Fire();
}
interface Itrank: IVehicle, Iweapon
{
void Run();
void Fire();
}
csharp
## int[],ArrayList都继承了ICollection类,所以都可用于foreach的迭代
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
int[] num1 = { 1, 2, 3, 4, 5 };
ArrayList num2 = new ArrayList { 1, 2, 3, 4, 5 };
Console.WriteLine(Sum(num1));
Console.WriteLine(Sum(num2));
Console.ReadKey();
}
static int Sum(ICollection nums)
{
int sum = 0;
foreach(var n in nums)
{
sum += (int)n;
}
return sum;
}
}
}
csharp
//接口的显示实现,c#独有
//void Ikill.Kill()//显示实现所有成员时, wk.Kill()是调不到此方法的
//Ikill ikill = wk; ikill.Kill(); 只有Ikill变量时,才能调用Kill()方法
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
var wk = new Warmkill();
wk.Kill();
Ikill ikill = wk;
ikill.Kill();
Console.ReadKey();
}
interface Igentleman
{
void Love();
}
interface Ikill
{
void Kill();
}
class Warmkill : Igentleman, Ikill
{
public void Love()
{
Console.WriteLine("love you");
}
void Ikill.Kill()//显示实现所有成员
{
throw new NotImplementedException();
}
}
}
}
开发在编译代码的时候相当于静态代码,软件给用户使用时,处于dynamic状态,需要交互。开发可以枚举1000种方法来处理用户可能的操作,但太臃肿,也有可能覆盖不到,所以需要自己程序可以以不变应万变的能力,这个能力就是反射
反射可以不用new的情况,创建与类一个的类型,而且可访问其内部方法,相当于解耦合(用new创建时,后面要接类型,一有类型就有依赖)
普通反射
反射的用途1-依赖注入:用注册的动态类型,创建的实例,注入到Driver构造器中
反射的用途2-利用反射追求更松的耦合
七、泛型(这里代码多练习)
1.类型膨胀,1000种产品就会有1000种box,不好维护
csharp
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Apple apple = new Apple() { Color="red"};
AppleBox applebox = new AppleBox() { cargo = apple };
Console.WriteLine(applebox.cargo.Color);
Book book = new Book() { Name = "shuji" };
BookBox bookbox = new BookBox() { cargo = book };
Console.WriteLine(bookbox.cargo.Name);
Console.ReadKey();
}
class Apple
{
public string Color { get; set; }//Color属性
}
class AppleBox { public Apple cargo { get; set; } }//cargo属性
class Book
{
public string Name { get; set; }
}
class BookBox { public Book cargo { get; set; } }//cargo属性
}
}
2.成员膨胀:一个box类有多个属性,给不同的商品
3.通过向box中传objecet对象,可以快速装箱,但读取箱中内容时,不好操作
csharp
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Apple apple = new Apple() { Color="red"};
Book book = new Book() { Name = "shuji" };
Box box1 = new Box() { cargo = apple };
Box box2 = new Box() { cargo = book };
Console.WriteLine(box1.cargo.Color);//此处已经将book对象转换成object对象,无法再获得book对象中属性
Console.WriteLine((box1.cargo as Apple)?.Color);//可类型转换
Console.ReadKey();
}
class Apple
{
public string Color { get; set; }//Color属性
}
class Book
{
public string Name { get; set; }
}
//成员膨胀,一个box中有多个属性,每次只使用其中的一个,当新商品来时,还得修改此类
class Box {
public Object cargo { get; set; }
}
}
}
4.使用泛型不会产生类型膨胀、成员膨胀
csharp
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace ConsoleApp2
{
class Program
{
static void Main(string[] args)
{
Apple apple = new Apple() { Color="red"};
Book book = new Book() { Name = "shuji" };
//用泛型将box特化
Box<Apple> box1 = new Box<Apple>() { cargo = apple };
Box<Book> box2 = new Box<Book>() { cargo = book };
Console.WriteLine(box1.cargo.Color);
Console.WriteLine(box2.cargo.Name);
Console.ReadKey();
}
class Apple
{
public string Color { get; set; }//Color属性
}
class Book
{
public string Name { get; set; }
}
class Box<Tcargo> {
public Tcargo cargo{ get; set; }
}
}
}
5.泛型接口
泛型方法
成员膨胀
泛型方法(类型参数 加到zip方法后)
泛型委托
结构体类型是值类型,值类型:与值类型相关连的内存中存在的是此实例
值类型的copy: copy的是一个完整对象
变量类型的copy:是对同一个对象的引用(一份数据)
堆内存中的实例
结构体不能由其他结构体类型、类类型派生而来,只能由interface来
八、核心代码汇总
csharp
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Timers;
using System.Windows.Forms;
namespace Core_knowledge
{
public partial class Form1 : Form
{
//1类
//1.1属性方法定义
int a01 = 3;
public double Price { get; set; }
private void dosomething(string name)
{
Console.WriteLine($"[****Dosomething {name} start: 线程号:({Thread.CurrentThread.ManagedThreadId.ToString("00")})---{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}*******]");
long result = 0;
for (int i = 0; i < 10000000; i++)
{
result += i;
}
Thread.Sleep(2000);
Console.WriteLine($"[****Dosomething {name} end: 线程号:({Thread.CurrentThread.ManagedThreadId.ToString("00")})---{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}{result}*******]");
}
//1.2默认构造器 Student()是将数值型变成0,其他类型设置为null
Student stu = new Student();
//1.3构造器看着像方法,名子和类一样,有构造器后,引用创建对象时要传参否则报错-见class Student
Student stu2 = new Student(5, "timo");
//1.4初始化器{id=1,name="timothy" }
Student stu1 = new Student() { id = 1, name = "timothy" };
//1.5 析构器 ~Student() 函数在执行完后,说明这个对象没人用了就要释放,这里就会调用析构器,这里面可以写内存释放的代码
//1.6反射
/*
Type tt = typeof(Student);
object o = Activator.CreateInstance(tt, 15, "sss");
Student stu5 = o as Student;
Console.WriteLine(stu5.Name);*/
//1.7横向扩展对类成员的扩充,纵向扩展对类成员的重写
//1.8父类类型变量引用 子类类型实例 子类 is a 父类 汽车是车
public void s()
{
Vehicle v = new Car();//到底是哪个run,与实例化有关,谁被new,谁的被执行,这里是car running
v.run();
}
//1.9枚举-在定义一个person职位时,有人知道person有多少个level,有人不知道,所以放到enum中统一管理
public void meiju()
{
Console.WriteLine((int)Level.employee);
}
//1.10.见struct Student1 : ISpeak -结构体类型是值类型,值类型:与值类型相关连的内存中存在的是此实例
/*值类型的copy: copy的是一个完整对象
变量类型的copy:是对同一个对象的引用(一份数据) 堆内存中的实例
结构体不能由其他结构体类型、类类型派生而来,只能由interface来
*/
//2 IF_FOR_SWITCH
public void IF_FOR_SWITCH_foreach()
{
for (int c = 0; c < 5; c++)
{
int k = c;
Task.Run(
() =>
{
Thread.Sleep(100);
Console.WriteLine($"k={k}, i={c}");
}
);
}
int i = 0;
if (i > 10)
{
Console.WriteLine(1);
}
else if (i > 0 && i < 10)
{
Console.WriteLine(2);
}
else
{
Console.WriteLine(3);
}
switch (i)
{
case 1:
Console.WriteLine(1);
break;
case 2:
Console.WriteLine(1);
break;
default:
Console.WriteLine(1);
break;
}
int[] p = new int[] { 1, 2, 3 };
foreach (int p1 in p)
{
}
}
//3常用代码
public void Commoncode()
{
//数据类型
int q = 2;
int[] a = new int[6];
int[] b = new int[3] { 1, 2, 3 };
Console.WriteLine(a[1].ToString());
int[] c = new int[] { 'a', 2, 3 };
List<string> a1 = new List<string>() { "a", "b" };
Console.WriteLine(a1[1].ToString());
//List<Person> p = new List<Person>();
//p.Add(new Person() { });
a1.Add("112");
a[0] = 4;
a1.Insert(0, "3");
a1.RemoveAt(0);
a1.Remove("a");
a1.Clear();
Dictionary<int, string> d = new Dictionary<int, string> { //对象初始化器
{ 2,"333"},{4,"555"}
};
MessageBox.Show(c[0].ToString());
MessageBox.Show("1");
Console.WriteLine($"[------------主线程start: 线程号:({Thread.CurrentThread.ManagedThreadId.ToString("00")})---{System.DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}-----]");
}
//4Trycatch()
public void Trycatch()
{
try
{
if (2 > 1)
{
throw new Exception(string.Format($"执行失败"));
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
try
{
float a = 3;
double b = 3.2;
}
catch (AggregateException aex)
{
foreach (var item in aex.InnerExceptions)
{
Console.WriteLine(item.Message);
}
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
//5委托使用-委托相当于一个指针,可以指定任意方法,就可以实现方法调方法。
public void action()
{
//5.1.无返回值委托-Action委托
Calculator calculator = new Calculator();
Action action = new Action(calculator.Report);//Action: 方法是void,并且无参数
action.Invoke();//委托调用
Action<string> action = this.dosomething;//委托带参数
Action action1 = () => this.dosomething("CC");//委托不带参数
Logger logger = new Logger();
Action<Product> log = new Action<Product>(logger.Log);
//5.2.有返回值委托-Func委托
//<第一个int为返回值, 第二三个int为函数输入>
Func<int, int, int> func1 = new Func<int, int, int>(calculator.Add);//Func :方法是有返回,有参数
int x = 100;
int y = 200;
int z = 0;
int c = 0;
z = func1.Invoke(x, y);//委托调用
func1(x, y);//模仿c中函数指针的书写格式
//Product为委托的返回类型 ,func1为委托名 委托的返回值类型是Product,委托的函数名称=prodectFactory.MakePiza
//Func<Product> func1 = new Func<Product>(prodectFactory.MakePiza);
//5.3.委托简单使用-delegate自定义委托
//public delegate int Calc(int x, int y);//自定义委托是个类,格式要与委托函数一致
Calc calc1 = new Calc(calculator.Add);//委托实例化
c = calc1.Invoke(x, y);
//5.4.实现目的:方法中调用方法
//模板方法:方法中 输入 用委托类型参数封装的方法-具体看WrapProduct方法
//回调方法:方法中 在调用 用委托类型参数封装的方法 时,有条件判断-具体看WrapProduct方法
WrapFactory wrapFactory = new WrapFactory();
ProdectFactory prodectFactory = new ProdectFactory();
Action<Product> log1 = new Action<Product>(logger.Log);
Func<Product> func2 = new Func<Product>(prodectFactory.MakePiza);
//用委托将方法进行封装,然后将这个委托传到B方法中,在B方法中对委托进行调用,实现了方法中调用方的目的
//同时委托相当于一个指针,可以封装各式各样的方法,那么B方法也就可以调用任意方法
Box box1 = wrapFactory.WrapProduct(func2, log1);
//5.5.多播委托\异步委托调用
//直接同步调用:使用方法名
Student stu1 = new Student() { id = 1, pencolor = ConsoleColor.Yellow };
Student stu2 = new Student() { id = 1, pencolor = ConsoleColor.Yellow };
Student stu3 = new Student() { id = 1, pencolor = ConsoleColor.Yellow };
stu1.dohomework();
//5.6.间接同步调用:使用单播、多播委托invoke
Action action1 = new Action(stu1.dohomework);
Action action2 = new Action(stu2.dohomework);
Action action3 = new Action(stu3.dohomework);
action1.Invoke();//单播委托
action1 += action2;//多播委托
action1 += action3;
action1.Invoke();
//5.7.隐式异步调用:使用委托的begininvoke
Action action4 = new Action(stu1.dohomework);
action4.BeginInvoke(null, null);//第一个null为执行完线程后的回调函数
//5.8. 显示异步调用:使用thread或task
Thread thread1 = new Thread(new ThreadStart(stu1.dohomework));
thread1.Start();
}
//6.事件
public void shijian()
{
System.Timers.Timer timer = new System.Timers.Timer(); // timer.Elapsed事件的拥有者Timer
timer.Interval = 3000;
Boy boy = new Boy(); //事件的订阅者
Girl girl = new Girl();
// 订阅者的处理器 +=表示订阅 拿方法订阅一个事件时,它们要遵守约定:约定就是委托类型
// timer.Elapsed的类型就是 public delegate void ElapsedEventHandler(object sender, ElapsedEventArgs e);
// 所以使用alt+enter自动按照委托形式对boy.Action进行方法创建
timer.Elapsed += boy.Action; //timer.Elapsed 为事件,boy.Action为事件处理器
timer.Elapsed += girl.Action; //一个事件两个订阅者
timer.Start();
Console.ReadLine();
//三星:事件的拥有者是响应者的成员,见class Myform : Form
//事件自定义-可再找之间代码学习,学习过
}
//7.抽象类
//abstract抽象类-不能实例化:函数成员未被完全实现的类(无方法体),抽象类只能作为基类,为子类服务,子类进行重写 见-abstract class vehicle1
//abstract抽象类 一方面是用于子类继承,第二方法抽象类父类变量引用子类实例,代查
//concrete具体类
//8.接口-纯虚类-不能实例化 见class phoneuser、interface vehiclebase
public void jiekou() //(人--接口--(苹果手机,华为手机))多个人可分别使用不同款式手机
{
var user = new phoneuser(new nokia());
var user1 = new phoneuser(new erision());
user.usephone();
Console.Read();
//一个类多个可以多个接口,接口也可继承多个接口interface Itrank: IVehicle, Iweapon
var driver = new Driver(new Car1());
var driver1 = new Driver(new Truck());
driver.Drive(); driver1.Drive();
}
//9.反射的用途
//9.1.反射的用途-依赖注入: 用注册的动态类型,创建的实例,注入到Driver构造器中
//开发在编译代码的时候相当于静态代码,软件给用户使用时,处于dynamic状态,需要交互。开发可以枚举1000种方法来处理用户可能的操作,但太臃肿,也有可能覆盖不到,所以需要自己程序可以以不变应万变的能力,这个能力就是反射
//反射可以不用new的情况,创建与类一个的类型,而且可访问其内部方法,相当于解耦合(用new创建时,后面要接类型,一有类型就有依赖)
/*
public void fanshe()
{
Tank tank = new Tank();
var t = tank.GetType();
object o=Activator.CreateInstance(t);
MethodInfo fire= t.GetMethod("fire");
fire.Invoke(o, null);
}
public void zhuru()
{
var sc = new ServiceCollection();//建立容器
sc.AddScoped(typeof(ITank), typeof(MdediumTank));//typeof()获取类的动态参数,在容器中进行注册
var sp = sc.BuildServiceProvider();//建立服务
ITank tank=sp.GetService<ITank>();//使用
tank.fire();
tank.run();
}
//9.2反射的用途-利用反射追求更松的耦合--读第三方dll
EnvironmentVariableTarget assembly = AssemblyLoadContext.Defalut.Load....
*/
//10泛型
/*
1.类型膨胀,1000种产品就会有1000种box,不好维护 2.成员膨胀:一个box类有多个属性,给不同的商品
*/
List<int> list = new List<int>();//参考泛型写法:前面List类型中只能存放int类的变量
public void fanxing()
{
Apple apple = new Apple() { Color = "red" };
Book book = new Book() { Name = "shuji" };
//用泛型将box特化
Box<Apple> box1 = new Box<Apple> { cargo = apple };
Box<Book> box2 = new Box<Book>() { cargo = book };
Console.WriteLine(box1.cargo.Color);
Console.WriteLine(box2.cargo.Name);
//泛型接口
Student<int> stu = new Student<int>();
stu.ID = 101;
stu.Name = "asd";
}
//11.partial类 相当于一个类被切分成多个部分进行存放-要保持命名空间一致(namespace)
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
//Trycatch();
//Commoncode();
//shijian();
//Myform myform = new Myform();
//myform.ShowDialog();
fanxing();
}
}
class Calculator
{
public void Report()
{
Console.WriteLine("i have 3 methods");
}
public int Add(int a, int b)
{
int result = a + b;
return result;
}
public int Sub(int a, int b)
{
int result = a - b;
return result;
}
}
public delegate int Calc(int x, int y);//自定义委托是个类,格式要与委托函数一致
class Logger
{
public void Log(Product product)
{
Console.WriteLine("Product '{0}' created at {1},price is {2}", product.Name, DateTime.UtcNow, product.Price);
}
}
class Product
{
public string Name { get; set; } //类属性是string
public double Price { get; set; }
}
class Box
{
public Product product { get; set; }//类属性是一个类
}
class WrapFactory
{
//WrapProduct 委托的模板方法,Box方法的返回值
//委托模板方法的输入是委托函数 Func<Product> getProduct
public Box WrapProduct(Func<Product> getProduct, Action<Product> logCallback)
{
Box box = new Box();
Product product = getProduct.Invoke();
if (product.Price > 50)
{
logCallback(product);
}
box.product = product;
return box;
}
}
class ProdectFactory
{
public Product MakePiza()
{
Product product = new Product();
product.Name = "Pizza";
product.Price = 12;
return product;
}
public Product Makecar()
{
Product product = new Product();
product.Name = "car";
product.Price = 100;
return product;
}
}
class Student
{
public Student()//创建一个空的,给不传参使用,否则会报错
{
}
public Student(int Id, string Name)//构造器看着像方法,名子和类一样,有构造器后,引用创建对象时要传参否则报错
{
this.id = Id;
this.name = Name;
}
public static int Amount { get; set; }
static Student() { Amount = 100; }
~Student()
{
Console.WriteLine("bye bye");
}
public int id { get; set; }
public string name { get; set; }
public ConsoleColor pencolor { get; set; }
public void dohomework()
{
for (int i = 0; i < 5; i++)
{
Console.ForegroundColor = this.pencolor;
Console.WriteLine("student{0} doing homework {1} hours", this.id, i);
Thread.Sleep(1000);
}
}
}
class Boy
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("Jump");
}
}
class Girl
{
internal void Action(object sender, ElapsedEventArgs e)
{
Console.WriteLine("sing");
}
}
//三星:事件的拥有者是响应者的成员
class Myform : Form
{
private TextBox textBox;
private Button button;//form的字段成员,拥有者
public Myform()
{
this.button = new Button();
this.button.Location = new System.Drawing.Point(276, 176);
this.button.Size = new System.Drawing.Size(75, 23);
this.button.Text = "sss";
this.textBox = new TextBox();
this.textBox.Location = new System.Drawing.Point(176, 176);
this.textBox.Size = new System.Drawing.Size(120, 23);
this.Controls.Add(this.button);
this.Controls.Add(this.textBox);
this.button.Click += this.buttonCllicked; //form =响应者
}
private void buttonCllicked(object sender, EventArgs e)
{
this.textBox.Text = "hello world```````````````````````````";
}
}
class Vehicle
{
public Vehicle()
{
this.Owner = "NA";
}
public Vehicle(string owner)
{
this.Owner = owner;
}
public virtual void run()
{
Console.WriteLine("vehicle is running");
}
public string Owner { get; set; }
}
class Car : Vehicle
{
public Car()
{
this.Owner = "car";
}
//public Car() :base("NA")//基类构造器中有参数,子类构造器也要声明
//{
// this.Owner ="car owner";
//}
public void doing()
{
Console.WriteLine("222");
}
public override void run()
{
Console.WriteLine("car is running");
}
}
abstract class vehicle1
{
public void fill()//
{
Console.WriteLine("111");
}
public abstract void run1();//抽象方法
}
class car1 : vehicle1
{
public override void run1()
{
Console.WriteLine("111");
}
}
interface vehiclebase
{
void stop();
void fill();
}
class phoneuser
{
private iphone _phone;
public phoneuser(iphone phone)
{
_phone = phone;
}
public void usephone()
{
_phone.dail();
_phone.pickup();
_phone.send();
_phone.receive();
}
}
interface iphone
{
void dail();
void pickup();
void send();
void receive();
}
class nokia : iphone
{
public void dail()
{
Console.WriteLine("dailing........");
}
public void pickup()
{
Console.WriteLine("pickup......");
}
public void receive()
{
Console.WriteLine("receiving.......");
}
public void send()
{
Console.WriteLine("sending......");
}
}
class erision : iphone
{
public void dail()
{
Console.WriteLine("dailing-------");
}
public void pickup()
{
Console.WriteLine("pickup---------");
}
public void receive()
{
Console.WriteLine("receiving-------");
}
public void send()
{
Console.WriteLine("sending--------");
}
}
class Driver
{
private IVehicle _vehicle;
public Driver(IVehicle vehicle)
{
_vehicle = vehicle;
}
public void Drive()
{
_vehicle.Run();
}
}
interface IVehicle
{
void Run();
}
class Car1 : IVehicle
{
public void Run()
{
Console.WriteLine("car is running");
}
}
class Truck : IVehicle
{
public void Run()
{
Console.WriteLine("Truck is running");
}
}
interface Iweapon
{
void Fire();
}
interface Itrank : IVehicle, Iweapon
{
void Run();
void Fire();
}
class Tank{
void run()
{
}
void fire() { }
}
class Book
{
public string Name { get; set; }
}
class Apple
{
public string Color { get; set; }
}
class Box<Tcargo>
{
public Tcargo cargo { get; set; }
}
interface IUnique<TId>
{
TId ID { get; set; }
}
class Student<TId>: IUnique<TId>
{
public TId ID { get; set; }
public string Name { get; set; }
}
enum Level
{
employee=100,
manager,
boss=300,
}
interface ISpeak
{
void speak();
}
struct Student1 : ISpeak
{
public Student1(int id )//结构体不能使用显示无参函数,这里面必须有值
{
this.ID = id;
}
public int ID { get; set; }
public void speak()
{
Console.WriteLine("234");
}
}
}