C#笔记⑦
一、类
- 是一种数据结构——抽象类的数据结构(抽象出来的整体,如学生)
- 是一种数据类型——引用类型
- 代表现实世界中的”种类“
实例构造器,在实例化一个对象时候才会调用。
静态构造器,在加载类时就调用了
实例解析器,GC时会调用此解析器(~加类名())
基类 -> 派生类
父类 -> 子类
点击查看代码
class Test
{
static void Main(string[] args)
{
System.Console.WriteLine(Student.Amount);
Student stu1=new Student(1,"Tim");
Student stu2=new Student(2,"Tom");
System.Console.WriteLine($"{stu1.Name}同学获得{stu1.ID}");
System.Console.WriteLine($"{stu2.Name}同学获得{stu2.ID}");
System.Console.WriteLine(Student.Amount);
}
}
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public static int Amount { get; set; }
public Student(int id,string name) //实例构造器,在实例化对象时才调用
{
this.ID=id;
this.Name=name;
Amount++; //每次实例化一个对象,学生总数加一
}
static Student() //静态构造器,在加载类时就调用了
{
Amount=0;
}
~Student() //实例析构器
{
Amount--;
System.Console.WriteLine("学生解散了");
}
}
不用new也可以实例化对象(反射)
点击查看代码
class Test
{
static void Main(string[] args)
{
// Type t=typeof(Student);
// object o=Activator.CreateInstance(t,1,"Tim");
// Student stu=o as Student; //=(Student)o
// System.Console.WriteLine(stu.ID);
// System.Console.WriteLine(stu.Name);
Type t=typeof(Student);
dynamic stu=Activator.CreateInstance(t,1,"Tim");
System.Console.WriteLine(stu.ID);
System.Console.WriteLine(stu.Name);
}
}
class Student
{
public int ID { get; set; }
public string Name { get; set; }
public static int Amount { get; set; }
public Student(int id,string name) //实例构造器,在实例化对象时才调用
{
this.ID=id;
this.Name=name;
Amount++; //每次实例化一个对象,学生总数加一
}
static Student() //静态构造器,在加载类时就调用了
{
Amount=0;
}
~Student()
{
//Amount--;
System.Console.WriteLine("学生解散了");
}
}
二、类的访问级别
当声明class前无修饰时,默认internal,即使导入名称空间,也没法从外部引用,但在自身的项目(Assembly)程序集中的名称空间中自由访问。(exe或者dll)
想被外部所访问,要改为public。
三、类的继承
1. 横向对成员的扩展
2. 重写
子类的实例也时一个父类的实例
如果一个类前加sealed就无法被继承
一个类最多只有一个基类,多个基接口
如果有继承关系的话,会先触发父类的构造器,再子类的构造器,虽然继承关系就是将父类的属性、方法、事件继承了,但没继承构造器,所以只有构造器相同才能实例。
点击查看代码
class Test
{
static void Main(string[] args)
{
Car car=new Car();
System.Console.WriteLine(car.Owner);
}
}
class Vehicle
{
public Vehicle(string n)
{
Owner=n;
}
public string Owner { get; set; }
}
class Car:Vehicle
{
public Car():base("N/A") //调用base,在调用我们car构造器时将na的值传到父类
{
Owner="100";
}
}
一起改变构造器
class Test
{
static void Main(string[] args)
{
Car car=new Car("hh");
System.Console.WriteLine(car.Owner);
}
}
class Vehicle
{
public Vehicle(string n)
{
Owner=n;
}
public string Owner { get; set; }
}
class Car:Vehicle
{
public Car(string c):base(c) //将主方法体中的实参通过base传给父类构造器,形参名必须相同
{
}
}
四、访问控制
如果父类的成员被设为了private,只有父类自己可以访问,子类无法访问
如果父类的成员被设为了protected,在类中可以访问,当在主方法体无法访问,属于内部属性
点击查看代码
class Test
{
static void Main(string[] args)
{
Car car=new Car();
car.SpeedUp();
System.Console.WriteLine(car._rufuel);
System.Console.WriteLine(car._speed);
car.SuperSpeedUp();
System.Console.WriteLine(car._rufuel);
System.Console.WriteLine(car._speed);
}
}
class Vehicle
{
protected int _rpm { get; set; }
public int _rufuel { get; private set; }
public int _speed { get{return _rpm/100;} }
private void Rufuel()
{
_rufuel=100;
}
protected void Burn()
{
_rufuel--;
}
public void SpeedUp()
{
Burn();
_rpm+=1000;
}
public Vehicle()
{
Rufuel();
}
}
class Car:Vehicle
{
public void SuperSpeedUp()
{
Burn();
Burn();
_rpm+=2000;
}
}
五、重写与多态
重写与隐藏发生条件:
方法成员、可见、签名一致
父类用virtual修饰(虚)
子类用override修饰
必须是public或者protected
如果不用virtual与override,则会发生父类对子类的隐藏
结果为I Running
class Test
{
static void Main(string[] args)
{
Vehicle car=new Car();
car.Run();
}
}
class Vehicle
{
public void Run()
{
System.Console.WriteLine("I Running");
}
}
class Car:Vehicle
{
public void Run()
{
System.Console.WriteLine("NO");
}
}
如果实现了重写,也就是发生多态virtual与override,由自己所实例的对象决定
结果为NO
class Test
{
static void Main(string[] args)
{
Vehicle car=new Car(); //只有父类可以实例子类
car.Run();
}
}
class Vehicle
{
public virtual void Run()
{
System.Console.WriteLine("I Running");
}
}
class Car:Vehicle
{
public override void Run()
{
System.Console.WriteLine("NO");
}
}

浙公网安备 33010602011771号