C#从入门到入土(自学笔记)--Day3-创新互联

学习目标:
  • 新学的知识:能够写出代码,了解代码知识
  • 旧知识:区分形参和实参,引用类型等
  • 理解构造函数和实例化对象的意义(谢邀已晕)

学习内容:
  1. 结构体,枚举,类,继承,多态,重载基本知识语法

学习时间:
  • 2022/11/30 水曜日

学习产出:
  • 技术博客 1 篇
  • 代码

目录

创新互联建站公司2013年成立,先为墨玉等服务建站,墨玉等地企业,进行企业商务咨询服务。为墨玉企业网站制作PC+手机+微官网三网同步一站式服务解决您的所有建站问题。

学习目标:

学习内容:

学习时间:

学习产出:

C#枚举

C#结构体

C#类

构造函数:

类的静态(static)成员:

C#继承

C#多态

静态多态性:

动态多态性:

总结:


C#枚举

枚举(Enum)是命名整型常量,值类型,不可以继承

enum{ 
    enumeration list 
};

//enum_name 指定枚举的类型名称。
//enumeration list 是一个用逗号分隔的标识符列表。
//枚举列表中的每个符号代表一个整数值,一个比它前面的符号大的整数值。默认情况下,第一个枚举符号的值是 0,enum里的值是递增的,可以定义枚举的值

案例:
public class EnumTest
{
    enum Day { Sun=1, Mon, Tue, Wed, Thu, Fri, Sat };

    static void Main()
    {
        int x = (int)Day.Sun;
        int y = (int)Day.Fri;
        Console.WriteLine("Sun = {0}", x);
        Console.WriteLine("Fri = {0}", y);
    }
}

//"Sun = 1"
//"Fri = 6"

//要注意的是:enum只能在同类内使用


C#结构体

结构体:使一个单一变量可以存储各种数据类型的相关数据,结构体不可以赋初值。和类同级

特点:

  • 结构可带有方法、字段、索引、属性、运算符方法和事件。
  • 结构可定义构造函数,但不能定义析构函数。但是,您不能为结构定义无参构造函数。无参构造函数(默认)是自动定义的,且不能被改变。
  • 与类不同,结构不能继承其他的结构或类。
  • 结构不能作为其他结构或类的基础结构。
  • 结构可实现一个或多个接口。
  • 结构成员不能指定为 abstract、virtual 或 protected。
  • 当您使用 New 操作符创建一个结构对象时,会调用适当的构造函数来创建结构。与类不同,结构可以不使用 New 操作符即可被实例化。
  • 如果不使用 New 操作符,只有在所有的字段都被初始化之后,字段才被赋值,对象才被使用。
struct Books
    {
        private string title;
        private string author;
        private string subject;
        private int bookId;
        public void setValues(string t,string a,string s,int id)
        {
            title = t;
            author = a;
            subject = s;
            bookId = id;
        }
        public void display()
        {
            Console.WriteLine("Title : {0}", title);
            Console.WriteLine("Author : {0}", author);
            Console.WriteLine("Subject : {0}", subject);
            Console.WriteLine("Book_id :{0}", bookId);
        }

    }


class Program
    {
    static void Main(string[] args)
        {
            #region struct结构体
            Books book1 = new Books();
            Books book2 = new Books();

            book1.setValues("11", "222", "3333", 44444);
            book2.setValues("22", "333", "4444", 55555);
            book1.display();
            book2.display();
            #endregion
        }
    }

C#类
  • 类定义了类的对象由什么组成及在这个对象上可执行什么操作。
  • 对象是类的实例。构成类的方法和变量称为类的成员。
  • 我们定义一个类后,就必须实例化才给使用。实例化就是创建一个对象的过程
  • A a = new B(); 其中A是申明类,B是实例类。

成员变量是对象的属性(从设计角度),且它们保持私有来实现封装。这些变量只能使用公共成员函数来访问。

案例:

class Box
    {
       private double length;   // 长度
       private double breadth;  // 宽度
       private double height;   // 高度
       public void setLength( double len )
       {
            length = len;
       }

       public void setBreadth( double bre )
       {
            breadth = bre;
       }

       public void setHeight( double hei )
       {
            height = hei;
       }
       public double getVolume()
       {
           return length * breadth * height;
       }
    }
    class Boxtester
    {
        static void Main(string[] args)
        {
            Box Box1 = new Box();        // 声明 Box1,类型为 Box
            Box Box2 = new Box();        // 声明 Box2,类型为 Box
            double volume;               // 体积


            // Box1 详述
            Box1.setLength(6.0);
            Box1.setBreadth(7.0);
            Box1.setHeight(5.0);

            // Box2 详述
            Box2.setLength(12.0);
            Box2.setBreadth(13.0);
            Box2.setHeight(10.0);
       
            // Box1 的体积
            volume = Box1.getVolume();
            Console.WriteLine("Box1 的体积: {0}" ,volume);

            // Box2 的体积
            volume = Box2.getVolume();
            Console.WriteLine("Box2 的体积: {0}", volume);
           
            Console.ReadKey();
        }
    }
构造函数:

类的一个特殊的成员函数,当创建类的新对象时执行。构造函数的名称与类的名称完全相同,它没有任何返回类型。

构造函数的作用:

C#构造函数(超详解,建议收藏!!!)_Just Do Its的博客-博客_c#构造函数

当需要给一个类中的字段进行初始化时。第一种:实例化后手动给属性赋值;第二种实例化时直接把参数放进去自动给属性赋值

//无参构造函数
class Line
   {
      private double length;   // 线条的长度
      //在创建对象时就调用
      public Line()
      {
         Console.WriteLine("对象已创建");
      }

      //get,set函数,我的理解是,一个是从成员变量拿到函数中,一个从成员函数拿到数据,有一个通向外面的接口
      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line();    
         // 设置线条长度
         line.setLength(6.0);
         Console.WriteLine("线条的长度: {0}", line.getLength());
         Console.ReadKey();
      }
   }


//有参构造函数,在创建对象的同时给对象赋初始值
class Line
   {
      private double length;   // 线条的长度
      public Line(double len)  // 参数化构造函数
      {
         Console.WriteLine("对象已创建,length = {0}", len);
         length = len;
      }

      public void setLength( double len )
      {
         length = len;
      }
      public double getLength()
      {
         return length;
      }

      static void Main(string[] args)
      {
         Line line = new Line(10.0);
         Console.WriteLine("线条的长度: {0}", line.getLength());
         // 设置线条长度
         line.setLength(6.0);
         Console.WriteLine("线条的长度: {0}", line.getLength());
         Console.ReadKey();
      }
   }

在这插一下话,我感觉菜鸟教程很多都没有讲清楚,要不是我之前学过其他语言,多少有点领悟,说实在的真看不懂,在此贴一个截图,就是很基础的东西,但是教程直接告诉你就这么写,不会告诉为什么这么写。这段话真的是深入内心了已经是,恍然大悟(说明之前学的也不好)。然后我往后翻了一下,下面的教程其实也有关于属性的,但就是讲的太晚了,懵懵懂懂学到那有啥用。来自C#的类(史上最全总结)-不死鸟JGChttps://blog.csdn.net/jiangguangchao/article/details/108996447?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522166979052216782429732105%2522%252C%2522scm%2522%253A%252220140713.130102334..%2522%257D&request_id=166979052216782429732105&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2~all~top_positive~default-1-108996447-null-null.142%5Ev67%5Econtrol,201%5Ev3%5Eadd_ask,213%5Ev2%5Et3_control1&utm_term=C%23%E7%B1%BB&spm=1018.2226.3001.4187

析构函数:是类的一个特殊的成员函数,当类的对象超出范围时执行(程序认为可以垃圾回收的时候才会有用,反正我试了很多次都不成功,还以为是我的问题呢,结果上网一搜,纯粹是看C#“心情”哈哈哈哈)

class Line{
    ~Line() //析构函数
      {
         Console.WriteLine("对象已删除");
      }
}
类的静态(static)成员:

静态变量用于定义常量,因为它们的值可以通过直接调用类而不需要创建类的实例来获取。静态函数,这样的函数只能访问静态变量。

class StaticVar
    {
       public static int num;
        //count函数被调用几次,num值就+几次
        public void count()
        {
            num++;
        }
        public static int getNum()
        {
            return num;
        }
    }
    class StaticTester
    {
        static void Main(string[] args)
        {
            
            StaticVar s = new StaticVar();
            s.count();
            s.count();
            s.count(); 
            //静态方法不用实例化                 
            Console.WriteLine("变量 num: {0}", StaticVar.getNum());
            Console.ReadKey();
        }
    }

在菜鸟教程看到的笔记,最后一个,截个图C# 类(Class) | 菜鸟教程  。我觉得这才是静态方法的意义

1、使用 static 关键字修饰的类、字段、属性、方法等;

2、静态类只能包含静态成员;

3、静态成员可以使用类来访问;

这应该还有其他知识点,留位置:比如this什么的 


C#继承

基类和派生类

<访问修饰符>class<基类>{
 ...
}
class<派生类>:<基类>{
 ...
}


案例:

class Rectangle
   {
      // 成员变量
      protected double length;
      protected double width;
      public Rectangle(double l, double w)
      {
         length = l;
         width = w;
      }
      public double getArea()
      {
         return length * width;
      }
      public void Display()
      {
         Console.WriteLine("长度: {0}", length);
         Console.WriteLine("宽度: {0}", width);
         Console.WriteLine("面积: {0}", GetArea());
      }
   }//end class Rectangle  
   class Tabletop : Rectangle
   {
      private double cost;
      //子类继承父类时必须构造函数,并且带有相同的形参,并且后面要[ :base(参数) ]
      public Tabletop(double l, double w) : base(l, w)
      { }
      public double getCost()
      {
         cost = getArea() * 70;
         return cost;
      }
      public void Display()
      {
         base.Display();
         Console.WriteLine("成本: {0}", getCost());
      }
   }
   class ExecuteRectangle
   {
      static void Main(string[] args)
      {
         Tabletop t = new Tabletop(4.5, 7.5);
         t.Display();
         Console.ReadLine();
      }
   }

子类继承父类时必须构造函数,并且带有相同的形参,并且后面要加[ :base(参数) ] 。C#中的继承(详解)_木偶☜的博客-博客_c#继承 这个博客里有很详细的讲了base的关键字,不然还真不知道这个关键字干嘛的。

使用接口实现多重继承:菜鸟里有,案例中除了多了一个接口其他没变化,就只截个图记录一下。接口之后会学到。地址预留


C#多态
  1. 多态就是同一个接口,使用不同的实例而执行不同操作
  2. 在静态多态性中,函数的响应是在编译时发生的。在动态多态性中,函数的响应是在运行时发生的。
  3. 同一个事件发生在不同的对象上会产生不同的结果
静态多态性:
  • 函数重载
  • 运算符重载

函数重载:

两个重载函数必须在下列一个或两个方面有所区别:

  1. 函数的参数个数不同。
  2. 函数的参数类型不同或者参数类型顺序不同

本来我还是很懵逼的,然后看到了例子和重载的定义,我悟了大师,F12点开n那些关键字啥的不都是这个东西吗。

比如string字符串的方法中就有:

public int CompareTo(object? value);

public int CompareTo(String? strB);

这两个函数,功能都是一样的,返回值也一样,但是参数类型就是不一样啊。这就是多态性,重载的表现。

public class TestData  
    {  
        public int Add(int a, int b, int c)  
        {  
            return a + b + c;  
        }  
        public int Add(int a, int b)  
        {  
            return a + b;  
        }  
    }  
    class Program  
    {  
        static void Main(string[] args)  
        {  
            TestData dataClass = new TestData();
            int add1 = dataClass.Add(1, 2);  
            int add2 = dataClass.Add(1, 2, 3);

            Console.WriteLine("add1 :" + add1);
            Console.WriteLine("add2 :" + add2);  
        }  
    }

运算符重载:

重定义或重载 C# 中内置的运算符。因此,程序员也可以使用用户自定义类型的运算符。重载运算符是具有特殊名称的函数,是通过关键字 operator 后跟运算符的符号来定义的。有返回类型和参数列表。

class Box
    {
        private double length;
        private double breadth;
        private double height;
        public double getVolume()
        {
            return length * breadth * height;
        }

        public void setLength(double len)
        {
            length = len;
        }
        public void setBreadth(double bre)
        {
            breadth = bre;
        }
        public void setHeight(double hei)
        {
            height = hei;
        }
        //为Box类重载“+”运算符,其他不影响
        public static Box operator +(Box b, Box c)
        {
            Box box = new Box();
            box.length = b.length + c.length;
            box.breadth = b.breadth + c.breadth;
            box.height = b.height + c.height;
            return box;
        }
    }

class Program
    {
     static void Main(string[] args)
        {
            #region 运算符重载
            Box box1 = new Box();
            Box box2 = new Box();
            Box box3 = new Box();
            double volume = 0.0;

            box1.setLength(6.0);
            box1.setHeight(7.0);
            box1.setBreadth(5.0);
            box2.setLength(12.0);
            box2.setHeight(13.0);
            box2.setBreadth(15.0);

            volume = box1.getVolume();
            Console.WriteLine("box1 的体积: {0}", volume);
            volume = box2.getVolume();
            Console.WriteLine("box2 的体积: {0}", volume);
            //运算符重载的方法,+号代表重载过的方法
            box3 = box1 + box2;
            volume = box3.getVolume();
            Console.WriteLine("box3 的体积: {0}", volume);
        }
    }

可重载和不可重载的运算符:

C# 运算符重载 | 菜鸟教程

动态多态性:

动态多态性是通过 抽象类 和 虚方法 实现的。

  • 抽象类(abstract):抽象方法,在父类中的空方法,表示父类有这个功能,子类继承的话也会有,比如子类继承父类的唱歌方法,但是子类唱哪种风格的歌就和父类没啥关系了,反正都是会唱歌
    • 如果一个类中包含有抽象方法,那么这个类一定要声明为抽象类。
    • 同时,抽象方法一定需要在子类中重写。(因为没实现)
    • 抽象类不能(直接)实例化(继承的子类可以实例化)。
    • 通过在类定义前面放置关键字 sealed,可以将类声明为密封类。当一个类被声明为 sealed 时,它不能被继承。抽象类不能被声明为 sealed
  • 虚方法(virtual):父类中可以被子类继承重写的方法。(也可以不重写,因为虚方法是在父类中就已经实现了的)。对虚方法的调用是在运行时发生的,所以每次调用重写虚方法的子方法时,虚方法也会被调用。
  • 继承子类中的重写虚函数需要声明关键字 override,在方法参数传入中写(类名 形参名)例如 public void CallArea(Shape sh),意思是传入一个 shape 类型的类

C#中虚方法(virtual)详解_木偶☜的博客-博客_c# virtual

using System;
using System.Collections.Generic;

public class Shape
{
    //属性
    public int X { get; private set; }
    public int Y { get; private set; }
    public int Height { get; set; }
    public int Width { get; set; }
   
    // 虚方法
    public virtual void Draw()
    {
        Console.WriteLine("执行基类的画图任务");
    }
}

//下面三个是重写父类虚方法的方法
class Circle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("画一个圆形");
        base.Draw();
    }
}
class Rectangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("画一个长方形");
        base.Draw();
    }
}
class Triangle : Shape
{
    public override void Draw()
    {
        Console.WriteLine("画一个三角形");
        base.Draw();
    }
}

class Program
{
    static void Main(string[] args)
    {
        // 创建一个 List对象,并向该对象添加 Circle、Triangle 和 Rectangle
        var shapes = new List{
            new Rectangle(),
            new Triangle(),
            new Circle()
        };

        // 使用 foreach 循环对该列表的派生类进行循环访问,并对其中的每个 Shape 对象调用 Draw 方法
        foreach (var shape in shapes)
        {
            shape.Draw();
        }

        Console.WriteLine("按下任意键退出。");
        Console.ReadKey();
    }

}

总结:
  1. 紧赶慢赶把这一天该学的内容学完了,今天学到的内容有些绕,而且就算知道了概念,要在哪里运用我还是不太清楚。按照学了这么长时间代码来看,肯定是要再多加训练,多加练习写代码才行。
  2. 每天复习前面的知识,一定要复习,不然学习一天,回去就忘光了。
  3. 今天学习的知识有:结构体,枚举,类,继承,构造函数,静态,多态,虚方法,抽象类,函数重载,运算符重载。

你是否还在寻找稳定的海外服务器提供商?创新互联www.cdcxhl.cn海外机房具备T级流量清洗系统配攻击溯源,准确流量调度确保服务器高可用性,企业级服务器适合批量采购,新人活动首月15元起,快前往官网查看详情吧


本文名称:C#从入门到入土(自学笔记)--Day3-创新互联
链接分享:http://ybzwz.com/article/cdehio.html