AI教我学编程之C#类的基本概念(2)

news2024/11/15 8:46:33

前言

AI教我学编程之C#类的基本概念(2) 已经更新,欢迎道友们前往阅读,本节我们继续学习C#类的基本概念

目录

  • 上节回顾
    • 质疑
    • 对话AI
      • 特殊情况
      • 发问
      • 解释
  • 数据/函数成员
  • 类和程序–实现一个简单的程序
    • 实现尝试
  • 声明类
  • 类的成员
    • 字段
    • 方法
  • 总结

上节回顾

AI认为

1、一个类的目的是封装数据和行为,通过创建对象的实例使用这些数据和行为
2、类的组成元素有以下五个

  • 成员变量:用于存储对象的状态或属性。
  • 成员方法:用于定义对象的行为或操作。
  • 构造函数: 用于初始化对象的特定状态。
  • 属性(可选): 提供对成员变量的访问和修改的公共接口。
  • 事件(可选): 允许对象发布和订阅事件。

质疑

AI的回答其实并不完整,不知道大家还记不记得,在AI教我学编程之C#类型 这篇文章中,我们提到:类型声明包含数据成员函数成员,而类既然属于类型的一种,那么类是否也是由数据成员和函数成员组成的呢?由此,我们展开今天的学习

对话AI

程序员

类是否是由数据成员和函数成员组成的?
是,返回一个表格,表头:数据成员 | 函数成员
作用:数据成员的作用 | 函数成员的作用
内容:数据成员包含的元素 | 函数成员包含的元素
否,说出你的理由

在这里插入图片描述

类(Class)通常由数据成员(Data Members)和函数成员(Member Functions)组成。

以下是表格形式的回答:

类型数据成员函数成员
作用存储对象的属性和状态执行与对象相关的操作
内容包含对象的属性值,可以是各种数据类型包含方法(函数),操作或修改数据成员的方式

示例解释:

  1. 作用:

    • 数据成员的作用是存储类的对象的状态或属性。
    • 函数成员的作用是定义类的行为,执行各种操作。
  2. 内容:

    • 数据成员包含类的属性,这些属性可以是整数、浮点数、字符等各种数据类型。
    • 函数成员包含类的方法,这些方法定义了对象的行为。函数成员可以访问和修改数据成员,执行某些操作。

理由:

  • :因为这是面向对象编程(OOP)的基本原则,类通过数据成员表示对象的状态,通过函数成员表示对象的行为。
  • :在一些特殊的编程语境中,可能存在只有数据成员或只有函数成员的情况,但这不是通常的面向对象编程范例。通常,数据成员和函数成员一起构成类,形成封装的概念。
特殊情况

程序员

“在一些特殊的编程语境中,可能存在只有数据成员或只有函数成员的情况”,举出实例以说明

在这里插入图片描述

在一些特殊的编程语境中,可能存在只有数据成员或只有函数成员的情况。下面是两个例子:

只有数据成员的情况:

class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y

# 在这个例子中,Point 类只包含数据成员 x 和 y,没有定义任何方法。
# 这种情况可能在表示简单的数据结构时出现,不需要额外的行为,只需要存储数据。

只有函数成员的情况:

class Calculator:
    @staticmethod
    def add(x, y):
        return x + y

    @staticmethod
    def subtract(x, y):
        return x - y

# 在这个例子中,Calculator 类只包含静态方法,没有实例变量。
# 这种情况可能在定义一组相关的功能时出现,这些功能不依赖于特定对象的状态。

这些例子突显了在某些情境下,一个类可能只包含数据成员或只包含函数成员,具体取决于设计和用途。

发问

那么我们就要问了,只存储数据,或者只存储方法能实现一个完整的程序吗?

显然是不能的

解释

程序员

那么只存储数据和只有函数成员是无法实现一个完整的程序的是吗

在这里插入图片描述

是的,通常情况下,只存储数据或者只有函数成员的类可能无法实现一个完整的程序。在实际开发中,我们通常需要结合数据和相关功能,使得类能够更好地模拟现实世界的对象或者提供所需的功能。

只存储数据的类: 这样的类可能无法完成实际的操作或者提供必要的功能。数据本身没有受到保护,也没有相关的行为。

只有函数成员的类: 这样的类可能缺乏存储状态的能力,无法在不同函数之间共享信息。没有数据的存储,类的实例无法保持状态或者记录信息。

一个完整的程序通常需要类既有数据成员用于存储状态,又有函数成员用于操作和处理这些数据。这种综合使用才能更好地满足程序的需求。

数据/函数成员

程序员

那么类中包含着哪些数据成员和函数成员呢?

在这里插入图片描述

数据成员函数成员
字段:类中的变量,用于存储对象的状态。方法: 类中定义的函数,用于执行特定的操作。
常量:类中的常量值,一旦设置不可更改。属性:类中对字段的封装,提供对字段的访问和修改。
构造函数:在创建对象时初始化对象的特定成员。
析构函数: 在对象销毁时执行的方法,用于清理资源等工作。
运算符: 重载类的运算符,允许对象参与特定类型的运算。
索引器: 允许对象像数组一样使用索引访问元素。
事件: 提供一种机制,允许类的实例与其他对象进行交互。

上文提到,数据成员配合函数成员才能实现一个完整的程序
那么一个程序中有多少个这样的组合呢?

类和程序–实现一个简单的程序

程序员

写一个图书馆系统程序,它的工作就是可以从中借阅书籍。它有三个类,分别是Book,Library和Reader,分别用来存储书籍信息,搜索书籍和存储读者信息,Book类中包含书籍标题,作者,书籍类型几个变量,Library类中可以实现添加,删除书籍功能,可以根据书籍类型搜索书籍,Reader类中包含读者姓名,已借阅书籍名称,类中可以实现借阅,归还书籍功能

在这里插入图片描述

类描述:

1. Book 类:
  • 数据成员:
    • Title: 书籍标题
    • Author: 作者
    • Genre: 书籍类型 (例如:小说、科幻、历史)
  • 函数成员:
    • DisplayDetails(): 显示书籍详细信息
2. Library 类:
  • 数据成员:
    • books: 存储图书馆中所有书籍的集合,初始化时包含一些示例书籍
  • 函数成员:
    • AddBook(book): 向图书馆添加一本书
    • RemoveBook(book): 从图书馆移除一本书
    • SearchByGenre(genre): 按照书籍类型搜索书籍
3. Reader 类:
  • 数据成员:
    • Name: 读者姓名
    • CurrentBooks: 读者当前借阅的书籍集合
  • 函数成员:
    • BorrowBook(book): 借阅一本书
    • ReturnBook(book): 归还一本书
    • ViewBorrowedBooks(): 查看当前借阅的书籍

程序实例化:

// 创建书籍对象
Book book1 = new Book("The Catcher in the Rye", "J.D. Salinger", "Novel");
Book book2 = new Book("1984", "George Orwell", "Dystopian Fiction");
Book book3 = new Book("To Kill a Mockingbird", "Harper Lee", "Classic");

// 创建图书馆对象
Library library = new Library();

// 向图书馆添加书籍
library.AddBook(book1);
library.AddBook(book2);
library.AddBook(book3);

// 创建读者对象
Reader reader1 = new Reader("Alice");
Reader reader2 = new Reader("Bob");

// 读者借阅和归还书籍
reader1.BorrowBook(book1);
reader2.BorrowBook(book2);
reader2.BorrowBook(book3);
reader1.ReturnBook(book1);

// 查看图书馆中特定类型的书籍
List<Book> novels = library.SearchByGenre("Novel");

// 查看读者当前借阅的书籍
reader2.ViewBorrowedBooks();

这个示例程序模拟了一个图书馆系统,包括图书馆管理书籍的功能、读者借阅和归还书籍的功能,以及按照书籍类型搜索书籍的功能。

实现尝试

程序员

要求这个程序可以在Windows窗体应用程序中实现,现补充具体描述
1、用一个表格代表图书馆,表格中的每一行由书籍的具体信息构成
如:《百年孤独》,马尔克斯,文学
2、点击表格的每一行,可以显示书籍的借阅状态
√ 可借阅 × 已借出
3、表格的下方,为一个按钮,点击按钮,可以向表格中添加书籍
4、按钮的下方,为读者姓名和读者当前借阅的书籍集合
如:雨果,《百年孤独》,《巴黎圣母院》

在这里插入图片描述

要实现以上要求,可以借助 C# 的 Windows 窗体应用程序。以下是一个简单的示例,使用 DataGridView 控件来表示图书馆,Button 控件用于添加书籍,以及在底部显示读者姓名和当前借阅的书籍。

using System;
using System.Collections.Generic;
using System.Windows.Forms;

namespace LibraryApp
{
    public partial class MainForm : Form
    {
        private Library library;
        private Reader currentReader;

        public MainForm()
        {
            InitializeComponent();
            InitializeLibrary();
        }

        private void InitializeLibrary()
        {
            library = new Library();
            // 添加一些示例书籍
            library.AddBook(new Book("The Catcher in the Rye", "J.D. Salinger", "Novel"));
            library.AddBook(new Book("1984", "George Orwell", "Dystopian Fiction"));
            library.AddBook(new Book("To Kill a Mockingbird", "Harper Lee", "Classic"));

            // 显示图书馆内容
            UpdateLibraryGridView();
        }

        private void UpdateLibraryGridView()
        {
            // 清空表格
            libraryGridView.Rows.Clear();

            // 添加每本书的信息到表格
            foreach (var book in library.GetBooks())
            {
                string[] bookInfo = { book.Title, book.Author, book.Genre, book.IsAvailable ? "√" : "×" };
                libraryGridView.Rows.Add(bookInfo);
            }
        }

        private void addButton_Click(object sender, EventArgs e)
        {
            // 打开添加书籍窗口
            AddBookForm addBookForm = new AddBookForm(AddBookToLibrary);
            addBookForm.ShowDialog();
        }

        private void AddBookToLibrary(Book book)
        {
            library.AddBook(book);
            UpdateLibraryGridView();
        }

        private void libraryGridView_CellClick(object sender, DataGridViewCellEventArgs e)
        {
            // 点击表格的每一行,显示借阅状态
            if (e.RowIndex >= 0 && e.RowIndex < libraryGridView.Rows.Count)
            {
                string bookTitle = libraryGridView.Rows[e.RowIndex].Cells[0].Value.ToString();
                Book selectedBook = library.GetBookByTitle(bookTitle);

                if (selectedBook != null)
                {
                    MessageBox.Show($"借阅状态:{(selectedBook.IsAvailable ? "可借阅" : "已借出")}");
                }
            }
        }

        private void borrowButton_Click(object sender, EventArgs e)
        {
            // 模拟读者借阅书籍
            currentReader = new Reader("雨果");
            currentReader.BorrowBook(library.GetBookByTitle("The Catcher in the Rye"));
            currentReader.BorrowBook(library.GetBookByTitle("1984"));

            // 更新读者信息
            UpdateReaderInfo();
        }

        private void UpdateReaderInfo()
        {
            // 显示读者姓名
            readerNameLabel.Text = $"读者姓名:{currentReader.Name}";

            // 显示读者当前借阅的书籍
            currentBooksLabel.Text = $"当前借阅:{string.Join(",", currentReader.GetCurrentBooks())}";
        }
    }
}

请注意,上述示例只是演示了如何在 Windows 窗体应用程序中实现要求的功能。你可能需要创建相应的窗体和控件,并将代码适配到你的具体环境和需求。

不好意思诸位,目前还没有测试成功,容我再研究研究,之后再行更新
今天我们接着往下看

声明类

对于由C#定义的类型,我们可以直接使用,如int、double,但也有些类型如Person ,Car,这些我们自己定义的类型,需要通过class关键字声明才能使用
示例代码如下

class Person
{
    // 数据成员
    string name;
    int age;

    // 构造函数
    public Person(string name, int age)
    {
        this.name = name;
        this.age = age;
    }

    // 函数成员
    public void Greet()
    {
        Console.WriteLine("Hello, my name is {0} and I'm {1} years old.", name, age);
    }

    public void CelebrateBirthday()
    {
        age++;
        Console.WriteLine("Happy Birthday! Now I'm {0} years old.", age);
    }
}

class Car
{
    // 数据成员
    string model;
    int year;

    // 构造函数
    public Car(string model, int year)
    {
        this.model = model;
        this.year = year;
    }

    // 函数成员
    public void StartEngine()
    {
        Console.WriteLine("Engine started for {0} {1}.", year, model);
    }

    public void Drive()
    {
        Console.WriteLine("{0} {1} is now driving.", year, model);
    }
}

类的成员

我们刚才说到类的成员有很多,但是只有字段方法是最重要的类成员类型,字段是数据成员,方法是函数成员

字段

程序员

说说你对类的成员“字段”的理解
在这里插入图片描述
字段(Field):

字段是类的成员之一,用于保存数据。每个字段都有一个类型和一个标识符,可以被读取。

声明字段:

class MyClass
{
    int F1 = 17;         // 隐式初始化,初始值为 17
    string F2;           // 隐式初始化,默认值为 null
    int F3 = 25;         // 显式初始化,初始值为 25
    string F4 = "abcd";  // 显式初始化,初始值为 "abcd"
}

字段初始化:

字段可以通过等号后面跟着一个求值表达式进行初始化。如果没有初始化语句,字段的值会被编译器设为默认值,由字段的类型决定。

多个字段声明:

可以通过逗号分隔名称的方式,在同一条语句中声明多个相同类型的字段。不能在一个声明中混合不同类型的字段。

class MyClass
{
    int F1, F3 = 25;      // 声明两个 int 类型字段,F1 隐式初始化为 0
    string F2, F4 = "abcd"; // 声明两个 string 类型字段,F2 隐式初始化为 null
}

这样,字段在类中起到保存数据的作用,可以根据需要进行初始化。

方法

程序员

说说你对类的成员“方法”的理解
在这里插入图片描述
方法(Method):

方法是具有名称的可执行代码块,可以从程序的不同地方执行,甚至可以在其他程序中执行。方法执行包含在其代码块中,并在完成后返回到调用它的位置。

声明方法:

class SimpleClass
{
    // 无返回值的方法
    void PrintNums()
    {
        Console.WriteLine("1");
        Console.WriteLine("2");
    }
}

方法特征:

  • 返回类型: 方法声明了返回值的类型。如果方法不返回值,返回类型被指定为 void
  • 方法名: 方法有一个名字,用于标识和调用它。
  • 参数列表: 方法可以有参数,参数通过一对空的圆括号表示。如果有参数,它们将在圆括号内列出。

注意事项:

  • C#中没有全局函数,所有方法必须声明在类型声明内部。
  • 方法必须包含返回类型或 void,没有默认的返回类型。

这样,方法在类中定义了可执行的操作,可以在程序中被调用执行。

总结

刚见面就要说再见,道友们,今天我们学习了C#类的相关知识,个中不足,还望谅解,后有时间会补充更新,感谢大家的喜爱,喜欢本文的话,给博主点个赞吧!记得收藏加关注哦!道友们的支持就是我更新的源动力!
回到顶部

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1387831.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何判断售卖的医疗器械产品是二类还是三类

售卖医疗器械需关注产品本身是否为一、二、三类医疗器械。第一类医疗器械为一般项目的经营范围无需取得备案或许可证即可销售。第二类医疗器械产品需办理第二类医疗器械的备案方可销售。第三类医疗器械需取得医疗器械经营许可证且许可证上的经营范围需与销售的产品对应方可销售…

漏洞复现-Yearning front 任意文件读取漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

关于 Error: Cannot find module ‘webpack/lib/RuleSet‘ 的详细解决方法(亲测有效)- 以及删除脚手架的方法

对于出现的这个错误&#xff0c;之前我也尝试了网上的多种解决方案&#xff0c;最终经过测试后&#xff0c;是通过将原来的 vue/cli 版本降级到 4.5.15 版本&#xff0c;最后再重新安装 node_modules 包 才得以解决。 下面是我将介绍怎么安装 4.5.15 版本的脚手架等。 &#x…

运筹说 第65期 | 动态规划的基本概念和基本原理

20世纪50年代初&#xff0c;美国数学家R. Bellman 等人在解决多阶段决策优化问题时提出了一种高效的求解方法——动态规划&#xff08;Dynamic Programming&#xff09;&#xff0c;该方法基于多阶段决策优化问题的特点&#xff0c;把多阶段问题转换为一系列互相联系的单阶段问…

【经典算法】有趣的算法之---遗传算法梳理

every blog every motto: You can do more than you think. 0. 前言 遗传算法是一种基于自然选择和遗传机制的优化算法&#xff0c;因此它通常被用于求解各种最优化问题&#xff0c;例如函数优化、特征选择、图像处理等。 一言以蔽之&#xff1a; 将数学中的优化问题&#xf…

人机协同中存在一个独特的时空体系

一、在人机协同中存在一个独特的时空体系 在人机这个独特的时空体系中&#xff0c;人和机器之间的时间和空间的交织和共同作用。 在时间维度上&#xff0c;人机协同体系中的人和机器具有不同的时间节奏和速度。人类有限的生命周期和有时候需要休息的需求使得他们的工作时间和生…

(2023版)斯坦福CS231n学习笔记:DL与CV教程 (3) | 正则化与最优化

前言 &#x1f4da; 笔记专栏&#xff1a;斯坦福CS231N&#xff1a;面向视觉识别的卷积神经网络&#xff08;23&#xff09;&#x1f517; 课程链接&#xff1a;https://www.bilibili.com/video/BV1xV411R7i5&#x1f4bb; CS231n: 深度学习计算机视觉&#xff08;2017&#xf…

Android 12+ MQTT适配

最终的解决方案是下载源码去改。我用的是已经修改好了的库&#xff0c;如果包名要自己的&#xff0c; 要注意&#xff1a; 1. compileSdk 34 和 targetSdk 34 改成33&#xff08;Android12&#xff09;或者34&#xff08;Android13&#xff09;。 2. 下载的 module 导入。 …

【设计模式之美】重构(三)之解耦方法论:如何通过封装、抽象、模块化、中间层等解耦代码?

文章目录 一. “解耦”概述二. 如何给代码“解耦”&#xff1f;1. 封装与抽象2. 中间层2.1. 引入中间层能**简化模块或类之间的依赖关系**。2.2. 引入中间层可以起到过渡的作用&#xff0c;能够让开发和重构同步进行&#xff0c;不互相干扰。 3. 模块化4. 其他设计思想和原则4.…

QT属性动画

时间记录&#xff1a;2024/1/15 一、介绍 属性动画类为QPropertyAnimation&#xff0c;类似于CSS的keyframes关键帧 二、分类及使用步骤 1.几何动画 &#xff08;1&#xff09;创建QPropertyAnimation对象 &#xff08;2&#xff09;setPropertyName方法设置属性名称&#…

谷歌验证码|某爬虫问答社区登录参数分析

关注它&#xff0c;不迷路。 本文章中所有内容仅供学习交流&#xff0c;不可用于任何商业用途和非法用途&#xff0c;否则后果自负&#xff0c;如有侵权&#xff0c;请联系作者立即删除&#xff01; 1.目标地址 aHR0cHM6Ly9iYnMubmlnaHR0ZWFtLmNuL21lbWJlci5waHA/bW9kPW…

高通平台开发系列讲解(PCIE篇)MHI (Modem Host Interface)驱动详解

文章目录 一、MHI驱动代码二、MHI读数据流程三、MHI写数据流程沉淀、分享、成长,让自己和他人都能有所收获!😄 📢MHI (Modem Host Interface)我们通过名字顾名思义知道,它是Modem与Host的桥梁。 MHI 可以很容易地适应任何外围总线,但它主要用于基于 PCIe 的设备。 MHI(…

ElasticSearch降本增效常见的方法 | 京东云技术团队

Elasticsearch在db_ranking 的排名不断上升&#xff0c;其在存储领域已经蔚然成风且占有非常重要的地位。 随着Elasticsearch越来越受欢迎&#xff0c;企业花费在ES建设上的成本自然也不少。那如何减少ES的成本呢&#xff1f;今天我们就特地来聊聊ES降本增效的常见方法&#x…

Odrive 学习系列三:在odrive工程中添加SEGGER RTT 日志输出功能

一、背景: 对于嵌入式来讲,有个日志输出真真真真的太重要啦! SEGGER JLink自带的RTT日志输出对于老嵌入式而言更是开发利器。 Odrive本身的工程是不带这个功能的,尽管使用stlink可以查阅寄存器等,但感觉还是差了点意思。因此在本系列第二节的基础上,希望能给Odrive工程添…

Notepad++编译运行C/C++程序

首先需要先下载一个C语言编译器-MinGW&#xff08;免费的&#xff09; 官网&#xff1a;http://www.mingw.org/&#xff08;加载太慢&#xff09; 我选择MinGW - Minimalist GNU for Windows download | SourceForge.net这个网址下载的 注意安装地址&#xff0c;后续配置环境…

unique()函数

这篇博客是本人在学习算法中遇到的一个常用的函数&#xff0c;记录分享给大家 注意 &#xff1a;unique&#xff08;&#xff09;函数是删除相邻的重复元素&#xff0c;并且返回的是去重范围后的第一个元素的地址&#xff0c;左闭右开 #include <bits/stdc.h> using na…

CAN-位填充

位填充定义&#xff08;Bit Stuffing&#xff09; 当CAN节点发送 逻辑电平&#xff08;显性dominant或隐性recessive&#xff09;为持续相同的5位时&#xff0c;它必须添加一位反向电平。 CAN接收 节点会自动删除这个新增的额外电平位。 位填充作用 1---位填充是为了防止突发…

Codeforces Round 114 (Div. 1) C. Wizards and Numbers(思维题 辗转相除+博弈 巴什博弈)

题目 t(t<1e4)组询问&#xff0c;每次询问(a,b)&#xff08;0<a,b<1e18&#xff09;&#xff0c; 不妨a<b&#xff08;a>b时需要交换两个数考虑&#xff09; ①令b减去a的k次方&#xff08;k>1&#xff09;&#xff0c;要求减完之后b非负 ②令bb%a 当a和…

华媒舍:溯源媒体发稿,助推品牌快速突破

在当今残酷竞争的市场环境中&#xff0c;品牌的快速突破变成了公司发展的关键之一。溯源新闻媒体发稿作为一项强有力营销推广方式&#xff0c;为品牌快速建立名气、提升口碑品牌形象提供了重要适用。下面我们就详细介绍如何给品牌订制溯源新闻媒体发稿对策&#xff0c;并探讨其…

目标检测-One Stage-YOLOv8

文章目录 前言一、YOLOv8的网络结构和流程二、YOLOv8的创新点三、创新点详解CSP、C3和C2fTaskAlignedAssigner 正样本分配策略Distribution Focal Loss关闭 Mosiac 总结 前言 终于到了YOLO系列最新最火爆的网络–YOLOv8&#xff0c;前面YOLOv5中已经提到ultralytics团队集成了…