dotnet 初步学习(二)

48 阅读5分钟

类的成员可以包含 field,attribute,method.

[public] class Class_name {}

创建类的实例对象 new Class_name();

属性存在的意义就是保护字段;对字段的赋值和取值进行限定。

属性的本质就是两个方法get(){}; set(value){}

类是不占用内存,而实例对象是占用内存的。


爱上了打开机费


静态和非静态的区别

静态类在这个项目中资源是共享。

①、在非静态类中,既可以有实例成员,也可以有静态成员

②、在调用实例成员的时候,需要使用对象名.实例成员;

③、在调用静态成员的时候,需要使用类名,静态成员名;

总结:

①、静态成员必须使用类名去调用,而实例成员使用对象名调用。

②、静态函数中,只能访问静态成员,不允许访问实例成员。

③、实例函数中,既可以使用静态成员,也可以使用实例成员。

④、静态类中,只允许出现静态成员。

⑤、静态类不能被实例化。

构造函数

构造函数用来创建对象,并且可以在构造函数中对对象进行初始化。

构造函数是用来创建对象的特殊方法,方法名和类名一样,没有返回值,不能写void

构造函数可以有参数,new对象的时候传递函数参数即可

如果不指定构造函数,则类有一个默认的无参构造函数。 如果指定了构造函数,则不再有默认的无参构造函数,需要无参构造函数,则需要自己来写。

构造函数可以重载,也就是说有多个参数不同的构造函数 卡三等奖

new关键字

在内存中开辟一块空间

在开辟的空间中创建对象

调用对象的构造函数初始化对象

this 关键字

①、代表当前类的实例对象

②、在类当中显示的调用当前类的构造函数

class Program
{
  static void Main(string[] args)
  {
    Person yen = new Person("YEN", 12, 120.0, 120.0, 120.0);
    yen.SayHello();

    Person yan = new Person("YAN");
    yan.SayHello();

  }
}


class Person
{
  public Person(string name, int age, double english, double math, double chinese)
  {
    this.Name = name;
    this.Chinese = chinese;
    this.Math = math;
    this.English = english;
  }
  // 在类中显示的调用类的构造函数,不需要的参数给予默认值
  public Person(string name) : this(name, 0, 0.0, 0.0, 0.0)
  {
    this.Name = name;
  }
  public Person() { }

  public void SayHello()
  {
    Console.WriteLine("我是 {0} 英语 {1}分 数学 {2}分 语文 {3}分  平均分{4:0.00}", this.Name, this.English, this.Math, this.Chinese, (this.English + this.Math + this.Chinese) / 3);
  }
}

析构函数

析构函数以~ 开头;析构函数程序结束时才调用。帮助我们释放资源。

class Person
{
    public Person()
    {
        
    }
    // 析构函数
    ~Person()
    {
    
    }
}

命名空间

发现vscode好像不太需要 手动导入命名空间

值类型和引用类型

值类型和引用类型在内存中存储的地方不一样

在传递值类型和引用类型的时候,传递的方式也不一样。

值类型我们称之为值传递,引用类型我们称之为引用传递

值类型的数据类型有:int,double,bool,char,decimal,struct,enum

引用类型有:string,自定义类

存储:

值类型的值是存储在内存的栈当中

引用类型的值是存在内存的堆中

字符串

字符串不可变性。可以将字符串看做是char类型的只读数组。

class Program
{
  static void Main(string[] args)
  {
    string content = "inspire";
    // 将字符串转成字符数组
    char[] chs = content.ToCharArray();
    Console.WriteLine(chs[0]);
    chs[0] = 'I';
    content = new string(chs);
    Console.WriteLine(content);
  }
}

字符串的方法

  1. 将字符串转换为char数组 char[] charArray = content.ToCharArray()
  2. 将字符数组转换为字符串 string content = new string(charArray)
  3. StringBuilder类基本使用
using System.Diagnostics;
using System.Text;

class Program
{
  static void Main(string[] args)
  {
    StringBuilder sb = new StringBuilder();
    // 创建计时器
    Stopwatch sw = new Stopwatch();
    sw.Start();
    for (int i = 0; i < 10000; i++)
    {
      // str += i;
      sb.Append(i);
    }

    sw.Stop();
    Console.WriteLine("sb {0}", sb.ToString());
    Console.WriteLine(sw.Elapsed);
  }
}
  1. 获取字符串的长度使用Length属性 str.Length
  2. 字符串转大小写 ToUpper(),ToLower()
  3. 比较两字符串使用content.Equals(_content)忽略大小写
  4. 截取字符串Substring(index,length)
  5. 是否包含指定的字符串str.Contains("YEN")
  6. 分割字符串str.Split(,StringSplitOptions.RemoveEmptyEntries)
  7. 以什么开头、以什么结尾StartsWith(string value) EndsWith(string value)
  8. int IndexOf(string value) 取子串value第一次出现的位置
  9. int LastIndexOf(string value)
  10. string Trim()
  11. string TrimEnd() ; string TrimStart()
  12. bool IsNullOrEmpty()
  13. int IndexOf(string value ,int startIndex)
  14. string string.Join(string value,string[] strArray);将数组以指定的字符转换为字符串
using System.Diagnostics;
using System.Text;

class Program
{
  static void Main(string[] args)
  {
    string str = "I love three things YEN in this world,sun,moon, and you.";
    char[] chs = { ' ', ',', '.' };
    string[] strArray = str.Split(chs, StringSplitOptions.RemoveEmptyEntries);
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < strArray.Length; i++)
    {
      sb.Append(strArray[i]);
    }
    string newStr = sb.ToString();
    Console.WriteLine("newStr {0}", newStr);
    if (newStr.Contains("YEN"))
    {
      string newStrReplace = newStr.Replace("YEN", "YAN");
      Console.WriteLine("newStr-replace {0}", newStrReplace);
    }
    string substr = newStr.Substring(newStr.IndexOf("YEN"));
    Console.WriteLine("substr {0}", substr);
  }
}

继承

我们可能会在一些类中,写一些重复的成员,我们可以将这些重复的成员,单独的封装到一个类中,作为这些类的父类

Student、Teacher、Driver 子类 派生类

Person 父类 基类

子类继承了父类,那么子类从父类那里继承过来了什么?

首先,子类继承了父类的属性和方法,但是子类并没有继承父类的私有字段

问题:子类有没有继承父类的构造函数?

子类没有继承父类的构造函数

创建子类对象的时候 首先在子类的内部调用父类无参构造函数,创建父类对象,让子类可以使用父类中的成员

如果在父类中重写了一个有参数的构造函数,那么无参的构造函数将不存在。子类掉不到,就会报错。

解决方法

①、在父类中重新添加无参构造函数

②、在子类中显示的调用父类的构造函数,使用关键字:base().

using System.Text;

class Program
{
  static void Main(string[] args)
  {
    Teacher teacher = new Teacher("YAN", 18, 'M', 666666);
  }
}



class Person
{
  private string? _name;
  private int _age;
  private char _gender;

  public Person(string name, int age, char gender)
  {
    this.Name = name;
    this.Age = age;
    this.Gender = gender;
  }
  public void Rest()
  {
    Console.WriteLine("have a rest");
  }
  public string? Name { get => _name; set => _name = value; }
  public int Age { get => _age; set => _age = value; }
  public char Gender { get => _gender; set => _gender = value; }
}

class Teacher : Person
{
  private int _id;
  public Teacher(string name, int age, char gender, int id) : base(name, age, gender)
  {
    this.Id = id;
  }
  // 使用new关键字可以重写继承自父类的方法
  public new void Rest()
  {
    Console.WriteLine("After class");
  }
  public int Id { get => _id; set => _id = value; }
}

继承的特性

继承的单根性:一个子类只能有一个父类。

继承的传递性

object 是所有类的基类,所有的类都间接或者直接继承自object类

new关键字的作用

  1. 创建对象
  2. 隐藏从父类那里继承过来的同名成员

12