You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

请教:跨类访问对象参数及在School类中统计各年级注册学生数

问题解答:跨类访问对象参数与学生注册统计功能实现

嘿,刚接触OOP确实容易绕晕,我来帮你拆解这两个问题,一步步说清楚:

一、从其他类访问对象参数的常用方法

咱们在C#里想从别的类访问某个对象的参数,主要有几种实用方式,按需选就行:

  • 公共属性(Public Properties):这是最常用的操作,把你想暴露的字段封装成公共属性,相当于给对象开了个合法的访问窗口。比如给Student类加个Grade属性:
public class Student
{
    public string Name { get; set; }
    public int Grade { get; set; } // 外部类能直接通过对象实例访问这个属性
}

之后其他类里就能用studentInstance.Grade来获取或者修改年级信息了。

  • 公共方法(Public Methods):如果不想让外部直接修改字段,或者需要加一些访问逻辑(比如只允许读取),可以写个公共方法返回参数。比如:
public class Student
{
    private int _grade; // 私有字段,外部不能直接碰

    public int GetGrade()
    {
        return _grade; // 通过方法返回,能控制访问权限
    }
}

外部类就调用studentInstance.GetGrade()来获取年级。

  • 内部访问(Internal修饰符):如果你的类都在同一个程序集里(比如同一个项目),可以用internal修饰字段或属性,这样同项目的类能访问,外部项目不行,适合模块化的场景。

二、实现School类的学生注册与年级人数统计

接下来是你要做的核心功能:让School类管理Student实例,还能统计各年级人数。我给你写个完整的示例代码,每一步都给你标注清楚:

1. 先定义Student类

先把学生的基本信息封装好,比如姓名和年级,用构造函数初始化更规范:

public class Student
{
    public string Name { get; } // 只读属性,构造时赋值,避免后续被随意修改
    public int Grade { get; }

    // 构造函数,创建学生时必须传入姓名和年级
    public Student(string name, int grade)
    {
        Name = name;
        Grade = grade;
    }
}

2. 定义School类

School类要负责存储学生、注册学生,还要统计人数。咱们把学生列表设为私有,只暴露必要的方法,保证数据安全:

public class School
{
    // 私有列表存注册的学生,外部不能直接修改,只能通过咱们提供的方法操作
    private List<Student> _enrolledStudents = new List<Student>();

    // 注册学生的方法,加个空判断避免无效注册
    public void EnrollStudent(Student student)
    {
        if (student == null)
            throw new ArgumentNullException(nameof(student), "不能注册空的学生对象哦");
        
        _enrolledStudents.Add(student);
        Console.WriteLine($"已成功注册学生:{student.Name},年级:{student.Grade}");
    }

    // 统计各年级人数的方法,返回一个字典:键是年级,值是人数
    public Dictionary<int, int> GetGradeStudentCount()
    {
        // 用LINQ分组统计,代码简洁高效
        return _enrolledStudents
            .GroupBy(student => student.Grade)
            .ToDictionary(group => group.Key, group => group.Count());
    }

    // 专门写个打印方法,方便直接展示统计结果
    public void PrintGradeCounts()
    {
        var gradeCounts = GetGradeStudentCount();
        Console.WriteLine("\n当前各年级注册学生人数:");
        // 按年级排序后打印,看起来更整齐
        foreach (var kvp in gradeCounts.OrderBy(k => k.Key))
        {
            Console.WriteLine($"年级 {kvp.Key}:{kvp.Value} 人");
        }
    }
}

3. 测试代码,看看效果

写个Main方法测试一下,模拟注册几个学生,然后打印统计结果:

class Program
{
    static void Main(string[] args)
    {
        // 创建学校实例
        var mySchool = new School();

        // 创建学生并注册
        mySchool.EnrollStudent(new Student("张三", 1));
        mySchool.EnrollStudent(new Student("李四", 1));
        mySchool.EnrollStudent(new Student("王五", 2));
        mySchool.EnrollStudent(new Student("赵六", 3));
        mySchool.EnrollStudent(new Student("孙七", 2));

        // 打印统计结果
        mySchool.PrintGradeCounts();
    }
}

备选方案:如果还没学LINQ

要是你还没接触LINQ,也可以用循环遍历的方式统计,逻辑更直观:

public Dictionary<int, int> GetGradeStudentCount()
{
    var gradeCounts = new Dictionary<int, int>();
    foreach (var student in _enrolledStudents)
    {
        if (gradeCounts.ContainsKey(student.Grade))
        {
            // 年级已存在,人数加1
            gradeCounts[student.Grade]++;
        }
        else
        {
            // 年级不存在,初始化为1
            gradeCounts[student.Grade] = 1;
        }
    }
    return gradeCounts;
}

三、给OOP新手老师的小建议

作为刚接触OOP的老师,你可以从封装、继承、多态这三个核心概念入手拆解知识点:

  • 比如这个例子里的封装:Student的属性封装成只读,School的学生列表设为私有,只暴露注册和统计方法,就是封装的体现,保证数据安全和代码可控。
  • 后续可以扩展功能,比如加Teacher类、Course类,或者给Student加Age属性,慢慢延伸到继承(比如做个GraduateStudent继承Student)。
  • 遇到困惑时,先画个简单的类图,理清类之间的关系(比如School和Student是聚合关系:学校包含多个学生),再写代码会清晰很多。

内容的提问来源于stack exchange,提问作者SherBear320

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.21 07:39:00