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

前言

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

目录

上节回顾

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#类的相关知识,个中不足,还望谅解,后有时间会补充更新,感谢大家的喜爱,喜欢本文的话,给博主点个赞吧!记得收藏加关注哦!道友们的支持就是我更新的源动力!
回到顶部

  • 27
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

积德行善.jpg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值