using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _01_类与对象
{
internal class Program
{
static void Main(string[] args)
{
//对象就是类的实例,使用new操作符根据一个类创建该类的实例化对象
//当我们创建一个类的同时,也会拥有一个数据类型,所以这个实例化出来的对象,都属于这个类型
People p1 = new People();
People p2 = new People();
//通过对象名.成员名称的方式来操作对象的成员
//设置 对象名.成员名称=值
p1.name = "老王";
p1.age = 20;
p1.sex = '男';
//获取 对象名.成员名称
Console.WriteLine(p1.name);
//使用 对象名.成员名称() 的方式调用对象的方法
p1.eat();
p2.name = "老李";
p2.eat();
}
}
//定义了一个名字为People的类
class People
{
//成员变量
public string name;
public int age;
public char sex;
double money;
//成员方法
public void eat()
{
//在类的方法中使用this来表示当前类创建的那个对象
Console.WriteLine($"{this.name}在吃饭");
//访问当前类的其他的成员的时候,可以省略this
Console.WriteLine($"{name}在吃饭");
money = 100;
this.money = 100;
}
public void sleep()
{
Console.WriteLine("睡觉");
}
//Dog
class Dog
{
string name;
string Color;
void eat()
{
Console.WriteLine("吃骨头") ;
}
void speat()
{
Console.WriteLine("汪汪汪");
}
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _02属性和字段
{
internal class Program
{
static void Main(string[] args)
{
People p1 = new People();
p1.Age = 140;
Console.WriteLine(p1.Age);
}
class People
{
//类拥有成员变量和成员方法
//类的成员可以通过访问修饰符限制可访问的范围,如果一个成员的访问修饰符为public,这个成员变量将会有可能被随意更改,出现一些意料之外的值
//如:name 可能是无字 age 可能为负数 sex 可能出现除了男和女之外的值....
public string name;
//为了保证对象的数据不被随意的更改,我们通过会使用属性来定义公开的成员变量,用字段定义私有的成员变量(字段一般使用小驼峰命名)
private int age;
public int Age
{
//获取Age属性的时候执行
get
{
Console.WriteLine("get方法执行了");
return age;
}
//设置Age属性的时候执行
set
{
//set方法有一个value,这个value就是修改之后的值
Console.WriteLine(value);
Console.WriteLine("set方法执行了");
if (value>0&&value<120)
{
age = value;
}
else
{
throw new Exception("Age不在有限的范围内 0-120");
}
}
}
}
//Dog 拥有Age Color Age不能小于0 不能大于20 Color必须是 白 黑 黄 花
class Dog
{
private int age;
public int Age
{
get {
return age;
}
set {
if (value>0&&value<20)
{
age = value;
}
else
{
throw new Exception("超出范围");
}
}
}
public enum Ecolor { 白,黑,黄,花}
public Ecolor Color;
private char color1;
private char[] colors = new char[] { '白', '黑', '黄', '花' };
public char Color1
{
get { return color1; }
set
{
if (colors.Contains(value))
{
color1 = value;
}
else
{
throw new Exception("Color的属性不在可选的范围内");
}
}
}
//有时候我们只需要定义一个公开的属性,不需要进行操作的拦截
private string name;
public string Name { get => name; set =>name=value; }
//语法糖
public string Name1 { get; set; }
//字段的默认值
private string a = "a的默认值";
//属性的默认值
private string b = "b和B的默认值";
public string B
{
get => b;
set =>b=value;
}
public string C { get; set; } = "C的默认值";
}
}
}
构造函数就是与类(或结构体)具有相同名称的成员函数,它在类中的地位比较特殊,不需要我们主动调用,当创建一个类的对象时会自动调用类中的构造函数。在程序开发的过程中,通常使用类中的构造函数来初始化类中的成员属性。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _03_构造函数
{
internal class Program
{
static void Main(string[] args)
{
//对象可以在初始化的时候进行对象成员的初始化
People p1 = new People() { Name="老王",Age=20};
People p2= new People("老李",20);
Console.WriteLine(p2.Name);
}
}
class People
{
public string Name { set; get; }
public int Age { set; get; }
//是否成年
private bool isAdult;
//在类中可以定义一个和class同名的方法,这个方法会在创建类的实例化对象的时候自动被执行,我们称之为构造函数
//不需要也不能设置返回值类型
//构造函数本身也是一个函数,可以定义形参接收参数
public People()
{
//因为构造函数,是在对象创建的时候执行的,因此在这里不能访问对象后续赋值的属性值,访问到的是数据类型的默认值
Console.WriteLine("无参构造函数执行了");
//Console.WriteLine(this.Name);
//Console.WriteLine(this.Age);
}
public People(string name,int age)
{
Console.WriteLine("有参构造函数执行了");
Console.WriteLine(name);
Console.WriteLine(age);
isAdult = age >= 18;
Name=name;
Age=age;
}
public void Test()
{
if (true)
{
}
}
}
}
类的析构函数是类的一个特殊的成员方法,当一个对象被释放时执行
被释放:C#有垃圾回收机制,当某个数据没有被任何一个变量所引用时,垃圾回收机制就会把这个对象当作垃圾给清除掉
析构函数:当类的某个对象被当作垃圾回收时,这个函数就会被触发(一般在析构函数中释放对资源的引用)
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _04_析构函数
{
internal class Program
{
static void Main(string[] args)
{
People p1=new People() { Name="老王"};
People p2 = new People() { Name = "老李" };
// p1 = null;
People p3 = p2;
p2 = null;
Console.ReadKey();
//强制启动垃圾回收
GC.Collect();
}
}
class People
{
public string Name { get; set; }
//定义一个析构函数,一个和类相同名字的函数,在函数名字前添加一个~
~People()
{
Console.WriteLine(Name+"即将被回收");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _05_静态成员
{
internal class Program
{
static void Main(string[] args)
{
People p1=new People();
p1.Test1();
p1.Name = "老李";
//如何访问静态成员?
//类名.xxx访问静态成员
//静态成员有什么作用:提供了一种可以不需要实例化对象,就可以访问类成员的一种方式
People.PeopleName = "老王";
People.Test2();
//类的静态成员和非静态成员存储的位置是不同的,
//非静态成员:存储在是实例化的对象上,每一个对象都有一份,
//静态成员:存储在类上,所有的实例共享一个成员(独一份)
//
Test t1 = new Test();
Test t2 = new Test();
t1.AddNum();
t2.AddNum();
t1.GetNum();//2
t2.GetNum();//2
}
}
class People
{
//非静态属性
public string Name { get; set; }
//非静态方法
public void Test1()
{
Console.WriteLine("我是非静态方法");
//在类的非静态方法中,可以访问所有的类型
Console.WriteLine(Name);
Console.WriteLine(PeopleName);
Test2();
}
//在类的成员添加static关键字,这个成员就是这个类的静态成员
//静态属性
public static string PeopleName { set; get; } = "人类";
//静态方法
public static void Test2()
{
//在类的静态方法中,只能访问静态的类成员
Console.WriteLine("我是静态方法");
//Console.WriteLine(Name);
Console.WriteLine(PeopleName);
// Test1();
Test3();
}
public static void Test3()
{
Console.WriteLine("另一个静态方法");
}
}
class Test
{
public static int num = 0;
public void AddNum()
{
num++;
}
public void GetNum()
{
Console.WriteLine(num);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _06_常量和只读变量
{
internal class Program
{
static void Main(string[] args)
{
Test t =new Test();
Console.WriteLine(t.a);
//t.a = 666; 报错, 因为修改了只读字段
}
}
class Test
{
//类的字段可以添加一个readonly标识,标识这个字段为只读的
public readonly int a = 1;
//静态的readonly字段只能在静态的构造函数中被修改
public static readonly int b = 2;
//自动将字段修改为静态的,也只能是静态的
public const int c = 3;
public Test()
{
a = 2;
// b = 4;//报错 因为在非静态构造函数中修改了静态只读字段
}
static Test()
{
// a = 2;//报错 因为在静态构造函数中,修改了只读字段
b = 4;
//c = 5; 常量不能被任意操作符修改
}
public void Fn()
{
//a = 10;//报错 因为在非构造函数中修改了只读字段
//b = 10;//报错 因为在非静态构造函数中修改了只读字段
}
}
}
C#是面向对象的编程语言,面向对象编程的四项基本原则:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _07_类的继承
{
internal class Program
{
static void Main(string[] args)
{
Student student1 = new Student() { Name="老王",Age=20,Sex='男',StudentId="20240123",School="888教室"};
student1.Study();
student1.Eat();
SamllStudent student2 = new SamllStudent() { Name = "小王", Age = 10 };
student1.Eat();
}
}
//一个类(作为基类)
class People
{
public string Name { get; set; }
public int Age { get; set; }
public char Sex { get; set; }
public void Eat()
{
Console.WriteLine("我会吃饭");
}
}
//一个类(作为派生类)
//在定义一个类的时候, 使用 :基类
//当一个类继承自另一个类的时候,子类将自动拥有父类的所有成员
class Student : People
{
public string StudentId { get; set; }
public string School { get; set; }
public void Study()
{
Console.WriteLine($"我是{Name},我在{School}学习");
}
}
//基类和派生类并不是绝对的,是相对的,一个类可以同时是基类和派生类
class SamllStudent : Student
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _08_继承类的构造
{
internal class Program
{
static void Main(string[] args)
{
Man m1=new Man() { Name="老李"};
Console.WriteLine(m1.Sex);
m1.Fn();
Console.WriteLine(m1.Name);
}
}
class People
{
public string Name { get; set; }
public char Sex { get; set; }
public readonly int IQ;
private Random r=new Random();
public People()
{
Console.WriteLine("1.People的构造函数");
IQ = r.Next(0,255);
}
}
class Man : People
{
//Man是这个类是继承自People.默认他的Sex是男
//当我们New一个类的时候,这个子类创建之前父类就应该先存在,因此会先执行父类的构造方法,进行父类的创建,然后在执行子类的构造方法
public Man()
{
Console.WriteLine("2.Man的构造函数");
Sex = '男';
}
//子类可以直接操作定义在父类中的属性和字段
public void Fn()
{
Name = "老王";
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _09_子类访问父类
{
internal class Program
{
static void Main(string[] args)
{
//new People("老王",'男');
Man m1=new Man();
Man m2 = new Man("老王");
}
}
class People
{
public string Name { get; set; }
public char Sex { get; set; }
//类里面可以拥有多个同名但是不同参数的方法
//当调用放啊的时候,会自动根据放传递的参数,选择不同的方法执行
public People()
{
Console.WriteLine("People的无参构造");
}
public People(string name,char sex)
{
Console.WriteLine("People的有参构造");
Name= name;
Sex = sex;
}
}
class Man : People
{
//子类被创建的时候,默认会执行父类的无参构造方法,不会执行有参构造方法
public Man()
{
Console.WriteLine("Man的无参构造");
}
//子类中使用bese表示父类
//使用this表示当前类
//在子类的构造方法后面添加:bese() 可以直接执行父类的构造方法
public Man(string name):base(name,'男')
{
Console.WriteLine("Man的有参构造");
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _10_多态_函数的重载
{
internal class Program
{
static void Main(string[] args)
{
//我们对类进行相同的new行为,出现了不同的效果,这个就可以理解为多态
new People();
new People("");
new People();
}
}
class People
{
//函数的重载
//可以在同一个范围内,对相同的函数有多个定义
//函数的定义必须彼此不同,可以是参数列表中的参数类型不同,也可以是参数的个数不同
//不能重载只有返回值类型不同的函数
public People()
{
Console.WriteLine("无参构造函数");
}
public People(string a)
{
Console.WriteLine("参数是string类型的构造函数");
}
public People(int a,string b)
{
Console.WriteLine("参数是int类型的构造函数");
}
public void Eat()
{
Console.WriteLine("我在吃饭");
}
public void Eat(string food)
{
Console.WriteLine("我在吃饭"+ food);
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _11_多态_运算符重载
{
internal class Program
{
static void Main(string[] args)
{
Box b1=new Box() { Length=10,width=120,Height=30};
Box b2 = new Box() { Length = 10, width = 20, Height = 30 };
//计算两个盒子的体积之和
Console.WriteLine(b1+b2);
//将两个盒子相减 生成一个新的Box
Box b3 = b1 - b2;
}
}
class Box
{
public double Length { get; set; }
public double width { get; set; }
public double Height { get; set; }
public double Volume
{
get
{
return Length*width*Height;
}
}
//重载+运算符 计算两个盒子的体积
//一个运算符的重载,其实就是一个方法,当对该类的对象进行对应的运算符操作的时候,会自动执行这个重载的运算符方法
//格式 public static 返回值类型 operator 要重载的运算符(参数)
public static double operator +(Box box1,Box box2)
{
return box1.Volume + box2.Volume;
}
public static Box operator -(Box box1, Box box2)
{
return new Box
{
width = box1.width = box2.width,
Height = box1.Height = box2.Height,
Length = box1.Length = box2.Length,
};
}
public static bool operator >( Box box1, Box box2)
{
return box1.Volume > box2.Volume;
}
public static bool operator < (Box box1, Box box2)
{
return box1.Volume < box2.Volume;
}
public static bool operator ==(Box box1, Box box2)
{
return box1.Volume == box2.Volume;
}
public static bool operator !=(Box box1, Box box2)
{
return box1.Volume != box2.Volume;
}
}
}
C#中可以创建抽象类,用于提供类的部分成员实现,当某一个类继承自这个抽象类的时候,需要手动实现这个类中的抽象成员
抽象类中可以包含抽象方法,这个抽象方法不能去实现,而是在某个类继承自这个抽象类的时候实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _12_抽象类
{
internal class Program
{
static void Main(string[] args)
{
Priner p1 = new ColorPrinter();
p1.print("666");
}
}
//abstract class 创建一个抽象类
abstract class Priner
{
public string Name { get; set; }
public int Price { get;set; }
//抽象类和普通的类最大的区别在于抽象类可以拥有抽象方法
//把某个方法修饰成抽象方法的时候,抽象方法不需要也不能实现内容
abstract public void print(string value) ;
}
//当某个类继承自一个抽象方法之后,必须实现这个抽象类中所有的方法
class ColorPrinter: Priner
{
//override 重写和实现抽象类中的抽象方法
public override void print(string value)
{
Console.WriteLine("打印彩色的内容"+value);
}
}
class BawPrinter : Priner
{
public override void print(string value)
{
Console.WriteLine("打印黑白的内容" + value);
}
}
class TherePrinter : Priner
{
public override void print(string value)
{
Console.WriteLine("打印3D的内容" + value);
}
}
}
类的动态多态是由抽象类和虚方法实现的
虚方法可以定义在一个类中,可以理解为是一个类中的抽象方法,只是这个抽象方法可以在类中实现们也可以在派生类中实现
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _13_虚方法
{
internal class Program
{
static void Main(string[] args)
{
People p1 = new Chinese();
p1.Speak();
People p2=new American();
p2.Speak();
//抽象方法和虚方法的区别?
//1.抽象方法只能写在抽象类中
//2.抽象方法必须在派生类中实现,虚方法不需要再派生类中实现,如果不实现,则使用基类的方法
}
}
class People
{
public string Name { get; set; }
public string Age { get; set; }
public char Sex { get;set; }
//访问修饰符 virtual 返回值类型 函数名(参数) {函数体};
public virtual void Speak()
{
Console.WriteLine("打招呼");
}
}
class Chinese : People
{
public override void Speak()
{
Console.WriteLine("吃了没?");
}
}
class American : People
{
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace _14_密封类和静态类
{
internal class Program
{
static void Main(string[] args)
{
// new Test2();
}
}
//给一个类添加sealed关键字之后,这个类就不能被其他的类所继承了
sealed class Test
{
}
//class Test1 : Test
//{
//}
//静态类
//在类的前面添加static关键字之后,就是定义了一个静态类,静态类中只能拥有静态成员,而且静态类不能被实例化(不能new)
static class Test2
{
}
}