1.抽象类
抽象类 C#允许吧类和方法,声明为 abstract 抽象类不能被实例化,抽象类可以包含普通的方法和抽象方法 类是一个模版,那么抽象类就是一个不完整的模版,我们不能使用不完整的模版去构造对象;那为什么吧某个类定义为抽象?这是因为抽象类不能直接去声明对象,使用抽象类创建对象语法不通过,是为了别人误操作使用这个类(把一个不完整的类构造对象),所以我们把这个类定义为抽象类
abstract 抽象,用在类前,就是将类声明为抽象类,抽象类不能被实例化
abstract class Enemy
{
public int age;
public int id;
public void Move()
{
Console.WriteLine("move");
}
// 比如模拟攻击,每个类攻击的方式都不一样,所以每个子类都需要去重写;对于下面这个方法来说,就没必要有函数体了;没有函数体就没有办法调用,只是包含了一个定义(声明),所有人都有一个攻击方法,怎么攻击 ?就需要到使用的子类中实现
public abstract void Attack();
}
子类继承父类,会报错是因为父类中有一个抽象方法成员,如果想要继承就必须实现这个方法,如果不实现,语法就不会通过
class Boss : Enemy
{
// 如何实现
public override void Attack()
{
Console.WriteLine("boss的攻击");
}
}
sealed 密封,不能被继承
class Base
{
// 密封方法,如果想要把某个方法声明为密封方法的话,必须是一个已经重写的方法
public virtual void Move()
{
Console.WriteLine("Base");
}
}
internal class Child : Base
{
// 方法重写 sealed 声明密封方法,私有的,不能在被重写,不能被当前类的子类所重写,防止重写某些类导致代码混乱,使用比较少
public sealed override void Move()
{
Console.WriteLine("重写后的密封方法");
}
}
internal class Child2 : Child
{
// 因为这个类的父类中 Move 方法已经被密封了,密封的方法不能再被重写
//public override void Move()
//{
//}
}
2.子类构造
在 C# 中,子类的构造函数需要调用父类的构造函数来完成对父类成员的初始化。子类构造函数可以选择调用父类的无参构造函数或者指定调用父类的有参构造函数。
1.在子类中调用父类的默认构造函数(无参)(会先调用父类中的,然后是子类中的),无参的构造函数会调用对应没有参数的;如果有参数的就对应调用有参数的构造函数
Class1 c1 = new Class1();
2.调用有参构造函数,调用父类里面的(会先调用父类的构造函数,然后是子类)
Class1 c2 = new Class1(10,18,100);
如何在子类中调用父类中的构造函数 :base();即使不写也会调用父类中的构造函数
public Class1()
{
Console.WriteLine("构造函数什么都没有");
}
有一个构造函数对将数据进行初始化赋值,通过base(age,id),把age,id当做参数传递给父类,调用父类中的构造函数
public Class1(int age, int id, int a) : base(age, id)
{
this.a = a;
}
注意的是,如果父类没有无参构造函数并且定义了有参构造函数,子类必须显式调用父类的有参构造函数来完成对父类成员的初始化。
3.只读字段
在 C# 中,可以使用 readonly
关键字来创建只读字段。只读字段在初始化后不能被修改,并且必须在声明的时候或者构造函数中进行初始化。以下是一个只读字段的例子:
public class MyClass
{
public readonly int MyField;
public MyClass()
{
MyField = 10; // 只读字段在构造函数中进行初始化
}
public void SomeMethod()
{
// MyField = 20; // 错误!只读字段不能在方法中修改
}
}
在上面的例子中,MyField
是一个只读字段,它在构造函数中被初始化为 10,并且不能在类的其他地方被修改。
只读字段的特点是一旦初始化后不能再被修改,可以在声明时或构造函数中初始化。
4.日期与时间
// DateTime,时间点 2023-8-30 15:03:30
// 创建一个DateTime的对象,设置一个时间
DateTime dt1 = new DateTime(2023,06,04);
Console.WriteLine(dt1);
// 获取当前时间
DateTime dt2 = DateTime.Now;
Console.WriteLine(dt2);
// 获取当前日期
DateTime currentDate = DateTime.Today;
Console.WriteLine(currentDate);
// Year 获取当前时间的年份
int year = dt2.Year;
Console.WriteLine(year);
// Month 月
Console.WriteLine(dt2.Month);
// Day 天
Console.WriteLine(dt2.Day);
// 将时间转换为字符串
string time = dt2.ToString();
Console.WriteLine(time);
// 将字符串转换为指定的对应时间
DateTime dt3 = DateTime.ParseExact("2023/06/04","yyyy/M/d",CultureInfo.InvariantCulture);
Console.WriteLine(dt3);
// 历法结算
// AddDays 返回一个多少天之后的日期,赋值是当前日期时间前的日期时间
DateTime dt4 = DateTime.Now.AddDays(100);
Console.WriteLine(dt4);
// TimeSpan 时间长度
// Subtract 当前时间 - 过去时间 可以计算时间差
TimeSpan t1 = DateTime.Now.Subtract(new DateTime(2019,5,16));
// TotalDays 以天数计算时间差
Console.WriteLine(t1.TotalDays);
// TotalHours 以小时计算时间差
Console.WriteLine(t1.TotalHours);
// TotalMilliseconds 以毫米计算时间差
Console.WriteLine(t1.TotalMilliseconds);
// TotalMinutes 以分钟计算时间差
Console.WriteLine(t1.TotalMinutes);
// TotalSeconds 以秒计算时间差
Console.WriteLine(t1.TotalSeconds);