前言
AI教我学编程之C#类的基本概念(2) 已经更新,欢迎道友们前往阅读,本节我们继续学习C#类的基本概念
目录
- 上节回顾
- 质疑
- 对话AI
- 特殊情况
- 发问
- 解释
- 数据/函数成员
- 类和程序–实现一个简单的程序
- 实现尝试
- 声明类
- 类的成员
- 字段
- 方法
- 总结
上节回顾
AI认为
1、一个类的目的是封装数据和行为
,通过创建对象的实例
来使用
这些数据和行为
。
2、类的组成元素有以下五个
- 成员变量:用于存储对象的状态或属性。
- 成员方法:用于定义对象的行为或操作。
- 构造函数: 用于初始化对象的特定状态。
- 属性(可选): 提供对成员变量的访问和修改的公共接口。
- 事件(可选): 允许对象发布和订阅事件。
质疑
AI的回答其实并不完整,不知道大家还记不记得,在AI教我学编程之C#类型 这篇文章中,我们提到:类型声明包含
着数据成员
和函数成员
,而类既然属于类型的一种,那么类是否也是由数据成员和函数成员组成的呢?由此,我们展开今天的学习
对话AI
类是否是由数据成员和函数成员组成的?
是,返回一个表格,表头:数据成员 | 函数成员
作用:数据成员的作用 | 函数成员的作用
内容:数据成员包含的元素 | 函数成员包含的元素
否,说出你的理由
类(Class)通常由数据成员(Data Members)和函数成员(Member Functions)组成。
以下是表格形式的回答:
类型 | 数据成员 | 函数成员 |
---|---|---|
作用 | 存储对象的属性和状态 | 执行与对象相关的操作 |
内容 | 包含对象的属性值,可以是各种数据类型 | 包含方法(函数),操作或修改数据成员的方式 |
示例解释:
-
作用:
- 数据成员的作用是存储类的对象的状态或属性。
- 函数成员的作用是定义类的行为,执行各种操作。
-
内容:
- 数据成员包含类的属性,这些属性可以是整数、浮点数、字符等各种数据类型。
- 函数成员包含类的方法,这些方法定义了对象的行为。函数成员可以访问和修改数据成员,执行某些操作。
理由:
- 是:因为这是面向对象编程(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#类的相关知识,个中不足,还望谅解,后有时间会补充更新,感谢大家的喜爱,喜欢本文的话,给博主点个赞吧!记得收藏加关注哦!道友们的支持就是我更新的源动力!
回到顶部