对象的行为 - 对象中的方法

19 阅读4分钟

专栏导航

类不仅有属性(特征),还有方法(行为)。这一周,我们深入学习如何在类中定义方法,让对象具有完整的功能。

在类中定义方法

回顾:

组织代码 - 方法/函数 我们学习了如何定义和调用独立的方法。

// 独立的方法
static double CalculateArea(double radius)
{
    return 3.14 * radius * radius;
}

类中的方法

方法可以定义在类内部,表示对象的行为。

class Circle
{
    public double Radius { get; set; }

    // 类中的方法
    public double CalculateArea()
    {
        return 3.14 * Radius * Radius;
    }
}

// 使用
Circle circle = new Circle();
circle.Radius = 5;
double area = circle.CalculateArea();  // 通过对象调用

独立方法 vs 类方法

特性独立方法类方法
位置类外部或 static类内部
调用方式直接调用通过对象调用
访问数据通过参数传递直接访问类成员
用途工具函数对象行为

this 关键字

什么是 this?

this 关键字指向当前对象的实例。

为什么要使用 this?

1. 区分局部变量和字段
class Person
{
    private string name;  // 字段

    // 没有使用 this
    public void SetName(string name)
    {
        name = name;  // 赋值给自己!没有修改字段
    }

    // 使用 this
    public void SetNameCorrect(string name)
    {
        this.name = name;  // 明确修改字段
    }
}
2. 明确引用当前对象
class Person
{
    public string Name { get; set; }

    public void Introduce()
    {
        Console.WriteLine($"我叫{Name}");  // 隐式使用 this
        Console.WriteLine($"我叫{this.Name}");  // 显式使用 this
    }
}

示例:使用 this

class Person
{
    private string name;
    private int age;

    public Person(string name, int age)
    {
        this.name = name;  // this.name 是字段,name 是参数
        this.age = age;
    }

    public void PrintInfo()
    {
        Console.WriteLine($"姓名:{this.name},年龄:{this.age}");
    }
}

// 使用
Person person = new Person("张三", 25);
person.PrintInfo();

this 的其他用途

返回当前对象(链式调用)
class Person
{
    private string name;

    public Person SetName(string name)
    {
        this.name = name;
        return this;  // 返回当前对象
    }

    public Person SetAge(int age)
    {
        this.age = age;
        return this;
    }

    public void PrintInfo()
    {
        Console.WriteLine($"姓名:{name},年龄:{age}");
    }
}

// 链式调用
Person person = new Person();
person.SetName("张三").SetAge(25).PrintInfo();

构造函数(Constructor)

什么是构造函数?

构造函数是一种特殊的方法,用于在创建对象时初始化对象。

构造函数的特点

  • 方法名与类名相同
  • 没有返回值类型
  • 创建对象时自动调用
  • 可以重载(多个构造函数)

默认构造函数

如果没有定义构造函数,编译器会自动提供一个无参数的构造函数。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
}

Person person = new Person();  // 使用默认构造函数
person.Name = "张三";
person.Age = 25;

自定义构造函数

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }

    // 自定义构造函数
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }
}

// 使用构造函数创建对象
Person person = new Person("张三", 25);
Console.WriteLine($"姓名:{person.Name},年龄:{person.Age}");

构造函数重载

可以定义多个构造函数,参数不同即可。

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }

    // 无参构造函数
    public Person()
    {
        Name = "未知";
        Age = 0;
    }

    // 两个参数的构造函数
    public Person(string name, int age)
    {
        Name = name;
        Age = age;
    }

    // 三个参数的构造函数
    public Person(string name, int age, string gender)
    {
        Name = name;
        Age = age;
        Gender = gender;
    }
}

// 使用不同的构造函数
Person p1 = new Person();                       // 无参
Person p2 = new Person("张三", 25);             // 两个参数
Person p3 = new Person("李四", 30, "男");       // 三个参数

使用 this 调用其他构造函数

class Person
{
    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }

    public Person(string name, int age)
        : this(name, age, "未知")  // 调用三个参数的构造函数
    {
    }

    public Person(string name, int age, string gender)
    {
        Name = name;
        Age = age;
        Gender = gender;
    }
}

实践:给 Person 类添加方法和构造函数

using System;

namespace Week8Practice
{
    class Person
    {
        // 私有字段
        private string name;
        private int age;
        private string gender;

        // 无参构造函数
        public Person()
        {
            name = "匿名";
            age = 0;
            gender = "未知";
        }

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

        // 设置姓名
        public void SetName(string name)
        {
            if (!string.IsNullOrWhiteSpace(name))
            {
                this.name = name;
            }
        }

        // 设置年龄
        public void SetAge(int age)
        {
            if (age >= 0 && age <= 150)
            {
                this.age = age;
            }
            else
            {
                Console.WriteLine("年龄必须在 0-150 之间!");
            }
        }

        // 设置性别
        public void SetGender(string gender)
        {
            this.gender = gender;
        }

        // 获取姓名
        public string GetName()
        {
            return name;
        }

        // 获取年龄
        public int GetAge()
        {
            return age;
        }

        // 获取性别
        public string GetGender()
        {
            return gender;
        }

        // 自我介绍
        public void Introduce()
        {
            Console.WriteLine($"大家好,我叫{name},今年{age}岁,性别{gender}。");
        }

        // 问候
        public void SayHello()
        {
            Console.WriteLine($"{name}向你问好:Hello!");
        }

        // 判断是否成年
        public bool IsAdult()
        {
            return age >= 18;
        }

        // 显示信息
        public void DisplayInfo()
        {
            Console.WriteLine($"=== 人员信息 ===");
            Console.WriteLine($"姓名:{name}");
            Console.WriteLine($"年龄:{age}");
            Console.WriteLine($"性别:{gender}");
            Console.WriteLine($"是否成年:{(IsAdult() ? "是" : "否")}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===== Person 类演示 =====\n");

            // 使用无参构造函数
            Console.WriteLine("--- 使用无参构造函数 ---");
            Person person1 = new Person();
            person1.DisplayInfo();
            Console.WriteLine();

            // 使用带参数的构造函数
            Console.WriteLine("--- 使用带参数的构造函数 ---");
            Person person2 = new Person("张三", 25, "男");
            person2.DisplayInfo();
            Console.WriteLine();

            // 修改属性
            Console.WriteLine("--- 修改属性 ---");
            person1.SetName("李四");
            person1.SetAge(16);
            person1.SetGender("女");
            person1.DisplayInfo();
            Console.WriteLine();

            // 调用方法
            Console.WriteLine("--- 调用方法 ---");
            person2.Introduce();
            person2.SayHello();
            Console.WriteLine($"年龄:{person2.GetAge()}岁");
        }
    }
}

输出:

===== Person 类演示 =====

--- 使用无参构造函数 ---
=== 人员信息 ===
姓名:匿名
年龄:0
性别:未知
是否成年:否

--- 使用带参数的构造函数 ---
=== 人员信息 ===
姓名:张三
年龄:25
性别:男
是否成年:是

--- 修改属性 ---
=== 人员信息 ===
姓名:李四
年龄:16
性别:女
是否成年:否

--- 调用方法 ---
大家好,我叫张三,今年25岁,性别男。
张三向你问好:Hello!
年龄:25岁

实践:Circle 类

using System;

namespace Week8Practice
{
    class Circle
    {
        private double radius;

        // 构造函数
        public Circle(double radius)
        {
            SetRadius(radius);
        }

        // 设置半径(带验证)
        public void SetRadius(double radius)
        {
            if (radius > 0)
            {
                this.radius = radius;
            }
            else
            {
                Console.WriteLine("半径必须大于0!");
                this.radius = 1;  // 默认值
            }
        }

        // 获取半径
        public double GetRadius()
        {
            return radius;
        }

        // 计算面积
        public double CalculateArea()
        {
            double pi = 3.1415926;
            return pi * radius * radius;
        }

        // 计算周长
        public double CalculateCircumference()
        {
            double pi = 3.1415926;
            return 2 * pi * radius;
        }

        // 显示圆的信息
        public void DisplayInfo()
        {
            Console.WriteLine($"=== 圆的信息 ===");
            Console.WriteLine($"半径:{radius:F2}");
            Console.WriteLine($"面积:{CalculateArea():F2}");
            Console.WriteLine($"周长:{CalculateCircumference():F2}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===== 圆的计算 =====\n");

            // 创建圆对象
            Circle circle1 = new Circle(5);
            circle1.DisplayInfo();
            Console.WriteLine();

            Circle circle2 = new Circle(10);
            circle2.DisplayInfo();
            Console.WriteLine();

            // 修改半径
            Circle circle3 = new Circle(3);
            Console.WriteLine("--- 原始半径 ---");
            circle3.DisplayInfo();

            Console.WriteLine("\n--- 修改半径为 8 ---");
            circle3.SetRadius(8);
            circle3.DisplayInfo();
        }
    }
}

输出:

===== 圆的计算 =====

=== 圆的信息 ===
半径:5.00
面积:78.54
周长:31.42

=== 圆的信息 ===
半径:10.00
面积:314.16
周长:62.83

--- 原始半径 ---
=== 圆的信息 ===
半径:3.00
面积:28.27
周长:18.85

--- 修改半径为 8 ---
=== 圆的信息 ===
半径:8.00
面积:201.06
周长:50.27

实践:BankAccount 类(银行账户)

using System;

namespace Week8Practice
{
    class BankAccount
    {
        private string accountNumber;
        private string ownerName;
        private double balance;

        // 构造函数
        public BankAccount(string accountNumber, string ownerName, double initialBalance)
        {
            this.accountNumber = accountNumber;
            this.ownerName = ownerName;
            Deposit(initialBalance);  // 使用存款方法初始化
        }

        // 存款
        public void Deposit(double amount)
        {
            if (amount > 0)
            {
                balance += amount;
                Console.WriteLine($"存款成功:{amount:C},当前余额:{balance:C}");
            }
            else
            {
                Console.WriteLine("存款金额必须大于0!");
            }
        }

        // 取款
        public void Withdraw(double amount)
        {
            if (amount > 0)
            {
                if (balance >= amount)
                {
                    balance -= amount;
                    Console.WriteLine($"取款成功:{amount:C},当前余额:{balance:C}");
                }
                else
                {
                    Console.WriteLine("余额不足!");
                }
            }
            else
            {
                Console.WriteLine("取款金额必须大于0!");
            }
        }

        // 查询余额
        public double GetBalance()
        {
            return balance;
        }

        // 显示账户信息
        public void DisplayAccountInfo()
        {
            Console.WriteLine($"=== 账户信息 ===");
            Console.WriteLine($"账号:{accountNumber}");
            Console.WriteLine($"户主:{ownerName}");
            Console.WriteLine($"余额:{balance:C}");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("===== 银行账户管理 =====\n");

            // 创建账户
            BankAccount account = new BankAccount("123456789", "张三", 1000);
            account.DisplayAccountInfo();
            Console.WriteLine();

            // 存款
            Console.WriteLine("--- 存款 ---");
            account.Deposit(500);
            Console.WriteLine();

            // 取款
            Console.WriteLine("--- 取款 ---");
            account.Withdraw(300);
            Console.WriteLine();

            // 取款失败
            Console.WriteLine("--- 取款失败 ---");
            account.Withdraw(2000);
            Console.WriteLine();

            // 显示最终信息
            Console.WriteLine("--- 最终账户信息 ---");
            account.DisplayAccountInfo();
        }
    }
}

输出:

===== 银行账户管理 =====

=== 账户信息 ===
账号:123456789
户主:张三
余额:¥1,000.00

--- 存款 ---
存款成功:¥500.00,当前余额:¥1,500.00

--- 取款 ---
取款成功:¥300.00,当前余额:¥1,200.00

--- 取款失败 ---
余额不足!

--- 最终账户信息 ===
=== 账户信息 ===
账号:123456789
户主:张三
余额:¥1,200.00

方法命名规范

类方法命名建议

动词开头:

CalculateArea()     // 计算
GetUserInfo()       // 获取
SetName()           // 设置
IsValidEmail()      // 验证
DisplayInfo()       // 显示

布尔方法用 Is/Has/Can:

IsAdult()           // 是否成年
HasPermission()     // 是否有权限
CanDrive()          // 是否能开车

本章总结

  • ✅ 学会了在类中定义方法
  • ✅ 理解了 this 关键字的作用
  • ✅ 掌握了构造函数的使用
  • ✅ 学会了构造函数重载
  • ✅ 实践了多个类的设计