ctrl +K +S 折叠代码
在一个方法前输入三个/,将自动出现以下代码
/// <summary>
/// summary表示这个方法的总的描述
/// </summary>
/// <param name="args">表示的是方法参数的描述</param>
Console.WriteLine(格式字符串,参数列表)
Console.WriteLine("{0}{1}{2}",填坑,填坑,填坑,填坑); 填坑数量允许比坑多,多的不输出。
Console.WriteLine("{0}{1}{2}"); 输出结果为 {0}{1}{2} (原样输出)
Console.WriteLine("{0}{1}{2}",1); 报错,填坑数量比坑少;
return num2>num1 ? num1:num2; 如果表达式(num2>num1)为真则返回第一个参数(num1),否则返回第二个参数(num2)
定义数组: int[] nums =new int[] {1,2,3}; 此数组的类型是int[] 不是int
其他定义方法 : int[] nums={1,2,3}; int[] nums=new int[3]; nums[0]=1; nums[1]=2; nums[2]=3;
错误定义方法:int[] nums=new int[10]{1,2,3}; 报错
Console.WriteLine(数组或类或结构) 将输出 数组或类或结构的类型名
产生随机数用 Random 类 并调用Next()方法
Random r=new Random(); 以当前系统时间为种子数
Random r=new Random(int seed); 以设定的seed为种子数
系统根据种子数进行一种算法,从而得出随机数。
例子:随机产生100个数字。
Random r =new Random();
for (int i=0;i<100;i++)
{
int res =r.next();
Console.WriteLine(res);
}
Next()方法有3个重载:
1.Next()没有参数 产生Int32无符号整数
2.Next(int num) 产生0到num的整数,左闭右开区间。
3.Next(int num1,int num2) 产生num1到num2的整数,左闭右开区间
注意事项:随机对象Random不要写在循环中(因为个循环时间很短,在很短的时候内创建多个Random对象,将会使产生的随机数重复)
一段让窗体移动的代码:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
// 默认情况下,窗体由操作系统分配位子
StartPosition = FormStartPosition.Manual;
Location = new Point(0, 0);
}
int seed = 5;
private void timer1_Tick(object sender, EventArgs e)//在窗体中拖一个Timer控件,并将其Enable属性设为true.
{
// Timer控件的Interval属性设为20,此时写在里面的东西20ms执行一次
Screen.GetWorkingArea(new Point(0, 0))作用是获取距离(0,0)点坐标的显示屏(不包括任务栏),返回Rectangle类型的对象
int x = Location.X;
if (x >= Screen.GetWorkingArea(new Point(0, 0)).Width - Width || x < 0)
{
seed = seed * (-1);
}
Location = new Point(x + seed, Location.Y);
}
// //实现点击按钮获取屏幕高和宽参数
// //实现点击按钮获取屏幕高和宽参数
private void btnGetScreen_Click(object sender, EventArgs e)
{
Rectangle rect = Screen.GetWorkingArea(new Point(0, 0));
Text = rect.Width + " " + rect.Height;
}
}
面向对象:
类字段成员默认为private
在字段上 ctrl+r+e 可以快速得到字段对应的属性
枚举:
定义枚举
enum 枚举名
{
可能取到的值1,
可能取到的值2,
可能取到的值3
}
标志枚举参考书《 CLR vis c# 》
结构:
定义结构
struct 结构
{
//变量
//方法
//构造函数
}
结构的使用:1.直接定义赋初值 2.使用构造函数赋初值
结构注意事项:除了常量(const)和static ,其他不允许为字段赋初值。
结构默认无参构造函数会自动提供,不能直接写无参数构造函数
结构的有参数构造方法必须为每一个字段赋初值,否则会报错
类与结构 : 当运行时需要使用面向对象的特征的时候,使用类,否则也可以用结构
当数据类型字段较多的时候多用类 少用结构
抛异常:throw new Exception ("~~~~~~~");
复习:
描述一个对象,从字段和方法两个方面进行讨论。
属性实际上就是一个访问字段的途径(本质是方法)
private int num;
public int Num
{
get { return num; }
set { num = value; }
}
本质就是:
public int get_Num()
{
return num;
}
public void set_Num(int value)
{
num = value;
}
属性不具备存储数据的能力,只能通过其访问数据。
当使用自动属性的时候,系统会自动生成一个后台的字段,用来存储数据。自动属性一定要成对存在。(自动属性就是没有定义字段存储数据的属性)
构造函数干嘛用?
答:为字段赋初值(也就是初始化)。没有初始化的字段 分别默认为 数字类型 0,字符类型\0 即空 ,bool类型 false, string类型 null。
继承中实例化子类对象,会调用父类构造方法吗?
答:会,顺序是先父后子。 默认情况下都是调用父类无参构造方法。
如何判断方法的重载(方法原型)
1、去掉所有的方法名前的东西
2、去掉括号中所有的参数名与花括号
3、比较,不重合的构成重载
继承是用于编写代码,方便程序员组织代码完成编程的一个方式,代码执行在计算机中永远是机器码,我们所说的继承只是从编码的逻辑来入手,所有的非私有成员都被继承下来了。
处理构造方法与私有成员没有被继承,其他的都继承下来了,在内存中,即使私有字段,子类对象中依旧存在对应的数据(内存级别)。
继承特点: 单根性,传递性,派生于object根类(c#)
shift+alt+F10 自动添加命名空
// 练习:
// 写一个Person和Student,姓名(name)性别(gender)年龄(age)由父类构造方法初始化
// 年龄默认为0,性别随机,姓名有子类指定调用
// 创建一个Student对象,并做自我介绍
// 同时实现:实例化一个Student对象,指定姓名,性别,年龄
父类写法:class Person
{
string name;
int age;
char gender;
public string Name
{
get { return name; }
set { name = value; }
}
public int Age
{
get { return age; }
set { age = value; }
}
public char Gender
{
get { return gender; }
set { gender = value; }
}
public Person(string name)
{
this.name = name;
Random r = new Random();
this.gender = r.Next() % 2 == 0 ? '男' : '女';
}
public Person(string name, int age, char gender)
{
this.name = name;
this.age = age;
this.gender = gender;
}
public Person() { }
}
子类写法:
class Student:Person
{
int chengji;
public int Chengji
{
get { return chengji; }
set { chengji = value; }
}
public void SayHello()
{
Console.WriteLine("你好,我叫{0},今年{1}岁了,我是{2}生,我的成绩是{3}分...",
Name,Age,Gender,chengji
);
}
//public Student(string name, int chengji)
// : base(name)
//{
// this.chengji = chengji;
//}
public Student(string name, int age, char gender, int chengji)
: base(name, age, gender)
{
this.chengji = chengji;
}
}
调用自身无参构造函数:
public StudentModel(string str):this()
{
// 注册
this.Text = str;
label.Text = "姓名";
btn.Text = "确定";
}
public StudentModel()
{
InitializeComponent();
}
里氏转换:1.子类直接赋值给父类 2.指向子类的父类,可以强制转化为对应的子类。
is运算符,用来判断父类对象是否可以转化为子类对象 ,格式:对象 is 类型。如果可以转化,就返回true,否则返回false。
多态就是 统一调用,不同实现。
private void button1_Click(object sender ,EventArgs e) previous上一个
{
1.为什么是object 答:可以处理任何类型
2.代表什么 答:表示触发该事件的对象
3.有什么用 答:统一处理
}
复习:
多态的实现,继承中,子类与父类有相同名字的方法(非重载)
先new一个子类对象。
Thinking UML(大象书)
ToString()方法是根类object提供的,目的在于所有对象都可以输出。
多态实现的保障
1.继承(里氏转换原则)
2.子类与父类有相同名字的方法(非重载)
抽象方法:
抽象方法与一般方法写法一样,唯一不同的有两点。
1.前面有关键字abstract
2.没有方法体(即没有大括号{})
注意事项: 抽象方法只能在抽象类中。 扩展:抽象成员只能在抽象类中
抽象类不能被实例化
抽象类可以有构造方法,其作用是为非抽象人员进行初始化,而不是为创建抽象类的实例而使用。
抽象类可以有非抽象成员
抽象类存在就是为了被继承,因此不允许为private
抽象方法就是为了让子类重写
抽象成员必须设定为public
抽象类例子:
abstract class Animal
{
// 普通成员
string name;
public string Name
{
get { return name; }
set { name = value; }
}
// 抽象的成员
public abstract int LegCount
{
get; //没有方法体
}
public abstract void Jiao();
}
class Dog : Animal
{
// 实现属性,就需要为他添加一个字段
int legCount = 4;
public override int LegCount
{
get { return legCount; }
}
public override void Jiao()
{
Console.WriteLine("汪汪...");
}
}
class Bird : Animal
{
int legCount = 2;
public override int LegCount
{
get { return legCount; }
}
public override void Jiao()
{
Console.WriteLine("叽叽");
}
}
抽象类补充:
* 首先抽象类依旧是一个描述对象的一个模板
* 在抽象类中有具体的成员,用来描述事物的具体部分
* 而由于描述的对象的多样性,会发现有一些方法等不太一样,
* 就可以将它这些方法等写成抽象的,由具体的类来实现
*
* 抽象类的派生类必须实现(重写)抽象成员,除非这个子类也是一个抽象类
*
* 1、明确抽象类也是描述对象的模板
* 2、如何写一个抽象类(抽像类中有什么成员)
* 3、如何实现抽象类
练习: 动物,计算器
抽象类例子:
namespace _07Shape练习
{
class Program
{
static void Main(string[] args)
{
// 练习:有个形状Shape类,派生出圆Circle、矩形Rectangle和正方形Square,
// 分别计算它们的面积Area和周长Perimeter
Circle c1 = new Circle(10);
double res = c1.Arare();
Console.WriteLine("面积是{0}",res.ToString("0.00"));
res = c1.Perimeter();
Console.WriteLine("周长为{0}",res);
Console.WriteLine();
Rectangle r1 = new Rectangle(3, 7);
Console.WriteLine("面积是{0},周长是{1}",r1.Arare(),r1.Perimeter());
Console.WriteLine();
Square s1 = new Square(10);
Console.WriteLine("面积是{0},周长{1}",s1.Arare(),s1.Perimeter());
Console.ReadKey();
}
}
abstract class Shape
{
public abstract double Arare();
public abstract double Perimeter();
}
class Circle : Shape
{
int r;
public int R
{
get { return r; }
set { r = value; }
}
public Circle(int r)
{
this.r = r;
}
public override double Arare()
{
// pi r^2
// return Math.PI * r * r;
return Math.PI * Math.Pow(r, 2);
}
public override double Perimeter()
{
return 2 * Math.PI * r;
}
}
class Rectangle : Shape
{
int height;
public int Height
{
get { return height; }
set { height = value; }
}
int width;
public int Width
{
get { return width; }
set { width = value; }
}
public Rectangle(int w, int h)
{
width = w;
height = h;
}
public override double Arare()
{
return width * height;
}
public override double Perimeter()
{
return 2 * (width + height);
}
}
class Square : Shape
{
int length;
public int Length
{
get { return length; }
set { length = value; }
}
public Square(int l)
{
length = l;
}
public override double Arare()
{
return Math.Pow(length, 2);
}
public override double Perimeter()
{
return 4 * length;
}
}
}
protected与internal访问范围不可比
* 1、什么是静态成员
* 前面有static修饰的成员
* 2、如何调用静态成员
* 直接使用“类名.成员”
* 3、什么是静态类
* 很多时候,可以发现一个静态的方法就是一个功能
* 有时一个类中的成员全部是静态
* 多半将这种类写成一个静态类
* 在类的前面加上一个static即可
静态构造方法是存在的
静态构造方法什么时候被调的?
答:第一次使用该类型的时候,由系统自动的调用。
静态对象从程序运行开始,到整个程序结束才会释放资源。 少用静态资源
静态类不允许被继承 因为静态类中有sealed
静态类不允许实例化 因为静态类中有abstract
推荐的书CLR vis C#
MSIL权威指南
静态类只能继承自object
接口与多态例子:
namespace _15接口与多态
{
interface IMyInterface
{
void Func();
}
class MyClass : IMyInterface
{
public void Func()
{
Console.WriteLine("shixianl"); ;
}
}
class Program
{
static void Main(string[] args)
{
MyClass m1 = new MyClass();
// m1.Func();
IMyInterface im1 = m1;
im1.Func();
Console.ReadKey();
}
}
}
推荐书 C#高级编程
MSDN
.net组建程序设计