404 Not Found

404 Not Found


nginx

实战:面向对象综合

银行账户系统

目标: 构建一个银行账户系统,使用类、继承和多态来管理不同类型的账户。

需求:

示例

CSHARP
using System;
using System.Collections.Generic;

class Account
{
    public string Owner { get; set; }
    public decimal Balance { get; protected set; }

    public Account(string owner, decimal balance)
    {
        Owner = owner;
        Balance = balance;
    }

    public virtual void Deposit(decimal amount)
    {
        if (amount <= 0)
        {
            Console.WriteLine("存款金额必须大于0");
            return;
        }
        Balance += amount;
        Console.WriteLine($"{Owner} 存入 {amount:C},余额 {Balance:C}");
    }

    public virtual void Withdraw(decimal amount)
    {
        if (amount <= 0)
        {
            Console.WriteLine("取款金额必须大于0");
            return;
        }
        if (amount > Balance)
        {
            Console.WriteLine($"{Owner} 余额不足,无法取款 {amount:C}");
            return;
        }
        Balance -= amount;
        Console.WriteLine($"{Owner} 取出 {amount:C},余额 {Balance:C}");
    }

    public virtual void DisplayInfo()
    {
        Console.WriteLine($"账户持有人:{Owner},余额:{Balance:C}");
    }
}

class SavingsAccount : Account
{
    public decimal InterestRate { get; set; }

    public SavingsAccount(string owner, decimal balance, decimal interestRate)
        : base(owner, balance)
    {
        InterestRate = interestRate;
    }

    public void ApplyInterest()
    {
        decimal interest = Balance * InterestRate;
        Balance += interest;
        Console.WriteLine($"{Owner} 获得利息 {interest:C},余额 {Balance:C}");
    }

    public override void Withdraw(decimal amount)
    {
        if (amount <= 0)
        {
            Console.WriteLine("取款金额必须大于0");
            return;
        }
        if (amount > Balance)
        {
            Console.WriteLine($"储蓄账户不能透支,余额 {Balance:C},无法取款 {amount:C}");
            return;
        }
        Balance -= amount;
        Console.WriteLine($"{Owner}(储蓄) 取出 {amount:C},余额 {Balance:C}");
    }

    public override void DisplayInfo()
    {
        Console.WriteLine($"[储蓄账户] 持有人:{Owner},余额:{Balance:C},利率:{InterestRate:P}");
    }
}

class CheckingAccount : Account
{
    public decimal OverdraftLimit { get; set; }

    public CheckingAccount(string owner, decimal balance, decimal overdraftLimit)
        : base(owner, balance)
    {
        OverdraftLimit = overdraftLimit;
    }

    public override void Withdraw(decimal amount)
    {
        if (amount <= 0)
        {
            Console.WriteLine("取款金额必须大于0");
            return;
        }
        if (amount > Balance + OverdraftLimit)
        {
            Console.WriteLine($"超过透支额度,可用 {Balance + OverdraftLimit:C},无法取款 {amount:C}");
            return;
        }
        Balance -= amount;
        Console.WriteLine($"{Owner}(支票) 取出 {amount:C},余额 {Balance:C},透支额度 {OverdraftLimit:C}");
    }

    public override void DisplayInfo()
    {
        Console.WriteLine($"[支票账户] 持有人:{Owner},余额:{Balance:C},透支额度:{OverdraftLimit:C}");
    }
}

class Program
{
    static void Main()
    {
        List<Account> accounts = new List<Account>
        {
            new SavingsAccount("张三", 10000m, 0.03m),
            new CheckingAccount("李四", 5000m, 2000m)
        };

        Console.WriteLine("=== 多态取款演示 ===");
        foreach (Account acc in accounts)
        {
            acc.Withdraw(6000m);
        }

        Console.WriteLine();
        Console.WriteLine("=== 存款与利息 ===");
        accounts[0].Deposit(2000m);
        ((SavingsAccount)accounts[0]).ApplyInterest();

        Console.WriteLine();
        Console.WriteLine("=== 账户信息 ===");
        foreach (Account acc in accounts)
        {
            acc.DisplayInfo();
        }
    }
}
▶ 试一试
TEXT
=== 多态取款演示 ===
储蓄账户不能透支,余额 ¥10,000.00,无法取款 ¥6,000.00
李四(支票) 取出 ¥6,000.00,余额 ¥-1,000.00,透支额度 ¥2,000.00

=== 存款与利息 ===
张三 存入 ¥2,000.00,余额 ¥12,000.00
张三 获得利息 ¥360.00,余额 ¥12,360.00

=== 账户信息 ===
[储蓄账户] 持有人:张三,余额:¥12,360.00,利率:3.00%
[支票账户] 持有人:李四,余额:¥-1,000.00,透支额度:¥2,000.00

图形面积计算器

目标: 使用抽象类和接口,实现多种图形的面积计算,并支持按面积排序。

需求:

示例

CSHARP
using System;
using System.Collections.Generic;

abstract class Shape : IComparable<Shape>
{
    public abstract double Area();

    public int CompareTo(Shape other)
    {
        if (other == null) return 1;
        return Area().CompareTo(other.Area());
    }

    public override string ToString()
    {
        return $"{GetType().Name} - 面积:{Area():F2}";
    }
}

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

    public Circle(double radius)
    {
        Radius = radius;
    }

    public override double Area()
    {
        return Math.PI * Radius * Radius;
    }

    public override string ToString()
    {
        return $"Circle(半径={Radius}) - 面积:{Area():F2}";
    }
}

class Rectangle : Shape
{
    public double Width { get; set; }
    public double Height { get; set; }

    public Rectangle(double width, double height)
    {
        Width = width;
        Height = height;
    }

    public override double Area()
    {
        return Width * Height;
    }

    public override string ToString()
    {
        return $"Rectangle({Width}x{Height}) - 面积:{Area():F2}";
    }
}

class Program
{
    static void Main()
    {
        List<Shape> shapes = new List<Shape>
        {
            new Circle(5),
            new Rectangle(4, 6),
            new Circle(2),
            new Rectangle(10, 3),
            new Circle(3.5)
        };

        Console.WriteLine("=== 排序前 ===");
        foreach (Shape s in shapes)
        {
            Console.WriteLine(s);
        }

        shapes.Sort();

        Console.WriteLine();
        Console.WriteLine("=== 按面积排序后 ===");
        foreach (Shape s in shapes)
        {
            Console.WriteLine(s);
        }

        Console.WriteLine();
        Console.WriteLine($"总面积:{TotalArea(shapes):F2}");
    }

    static double TotalArea(List<Shape> shapes)
    {
        double total = 0;
        foreach (Shape s in shapes)
        {
            total += s.Area();
        }
        return total;
    }
}
▶ 试一试
TEXT
=== 排序前 ===
Circle(半径=5) - 面积:78.54
Rectangle(4x6) - 面积:24.00
Circle(半径=2) - 面积:12.57
Rectangle(10x3) - 面积:30.00
Circle(半径=3.5) - 面积:38.48

=== 按面积排序后 ===
Circle(半径=2) - 面积:12.57
Rectangle(4x6) - 面积:24.00
Rectangle(10x3) - 面积:30.00
Circle(半径=3.5) - 面积:38.48
Circle(半径=5) - 面积:78.54

总面积:183.59

简单库存管理系统

目标: 使用泛型集合和事件,构建一个库存管理系统,当库存低于阈值时触发低库存事件。

需求:

示例

CSHARP
using System;
using System.Collections.Generic;

class Product
{
    public string Name { get; set; }
    public int Quantity { get; set; }
    public decimal Price { get; set; }
    public int LowStockThreshold { get; set; }

    public Product(string name, int quantity, decimal price, int lowStockThreshold)
    {
        Name = name;
        Quantity = quantity;
        Price = price;
        LowStockThreshold = lowStockThreshold;
    }

    public bool IsLowStock()
    {
        return Quantity < LowStockThreshold;
    }

    public override string ToString()
    {
        return $"{Name} - 数量:{Quantity},单价:{Price:C},阈值:{LowStockThreshold}";
    }
}

class LowStockEventArgs : EventArgs
{
    public Product Product { get; set; }
    public int CurrentQuantity { get; set; }

    public LowStockEventArgs(Product product, int currentQuantity)
    {
        Product = product;
        CurrentQuantity = currentQuantity;
    }
}

class Inventory
{
    private List<Product> products = new List<Product>();

    public event EventHandler<LowStockEventArgs> LowStockAlert;

    public void Add(Product product)
    {
        Product existing = FindByName(product.Name);
        if (existing != null)
        {
            existing.Quantity += product.Quantity;
            Console.WriteLine($"商品 {product.Name} 已存在,数量增加至 {existing.Quantity}");
        }
        else
        {
            products.Add(product);
            Console.WriteLine($"添加商品:{product.Name},数量:{product.Quantity}");
        }
        CheckLowStock(product);
    }

    public void Remove(string name, int quantity)
    {
        Product product = FindByName(name);
        if (product == null)
        {
            Console.WriteLine($"商品 {name} 不存在");
            return;
        }
        if (quantity > product.Quantity)
        {
            Console.WriteLine($"商品 {name} 库存不足,当前数量:{product.Quantity},请求移除:{quantity}");
            return;
        }
        product.Quantity -= quantity;
        Console.WriteLine($"移除商品 {name} 数量 {quantity},剩余 {product.Quantity}");
        CheckLowStock(product);
    }

    public Product FindByName(string name)
    {
        foreach (Product p in products)
        {
            if (p.Name == name)
            {
                return p;
            }
        }
        return null;
    }

    public void DisplayAll()
    {
        Console.WriteLine("=== 库存清单 ===");
        foreach (Product p in products)
        {
            string warning = p.IsLowStock() ? " ⚠️低库存" : "";
            Console.WriteLine($"{p}{warning}");
        }
        Console.WriteLine($"商品种类:{products.Count}");
    }

    protected virtual void OnLowStock(LowStockEventArgs e)
    {
        LowStockAlert?.Invoke(this, e);
    }

    private void CheckLowStock(Product product)
    {
        if (product.IsLowStock())
        {
            OnLowStock(new LowStockEventArgs(product, product.Quantity));
        }
    }
}

class Program
{
    static void Main()
    {
        Inventory inventory = new Inventory();
        inventory.LowStockAlert += OnLowStock;

        inventory.Add(new Product("键盘", 50, 299m, 10));
        inventory.Add(new Product("鼠标", 30, 99m, 10));
        inventory.Add(new Product("显示器", 5, 1999m, 10));

        Console.WriteLine();
        inventory.Remove("显示器", 2);
        inventory.Remove("键盘", 45);

        Console.WriteLine();
        inventory.Add(new Product("键盘", 3, 299m, 10));

        Console.WriteLine();
        Product found = inventory.FindByName("鼠标");
        if (found != null)
        {
            Console.WriteLine($"搜索结果:{found}");
        }

        Console.WriteLine();
        inventory.DisplayAll();
    }

    static void OnLowStock(object sender, LowStockEventArgs e)
    {
        Console.WriteLine($"💡 [低库存预警] {e.Product.Name} 当前数量 {e.CurrentQuantity},低于阈值 {e.Product.LowStockThreshold}");
    }
}
▶ 试一试
TEXT
添加商品:键盘,数量:50
添加商品:鼠标,数量:30
添加商品:显示器,数量:5
💡 [低库存预警] 显示器 当前数量 5,低于阈值 10

移除商品 显示器 数量 2,剩余 3
💡 [低库存预警] 显示器 当前数量 3,低于阈值 10
移除商品 键盘 数量 45,剩余 5
💡 [低库存预警] 键盘 当前数量 5,低于阈值 10

商品 键盘 已存在,数量增加至 8
💡 [低库存预警] 键盘 当前数量 8,低于阈值 10

搜索结果:鼠标 - 数量:30,单价:¥99.00,阈值:10

=== 库存清单 ===
键盘 - 数量:8,单价:¥299.00,阈值:10 ⚠️低库存
鼠标 - 数量:30,单价:¥99.00,阈值:10
显示器 - 数量:3,单价:¥1,999.00,阈值:10 ⚠️低库存
商品种类:3

❓ 常见问题

Q 储蓄账户取款时为什么不能透支?
A 储蓄账户的设计原则是保守理财,重写 Withdraw 方法时增加了余额检查,拒绝超过余额的取款请求。
Q 抽象类和接口在该选哪个?
A 如果有公共字段或默认实现,用抽象类(如 Shape 的 CompareTo);如果只定义行为契约,用接口(如 IComparable<T>)。可以同时使用两者。
Q 事件和委托有什么区别?
A 事件是委托的封装,外部只能通过 += 和 -= 订阅/取消,不能直接调用,提供了更安全的发布-订阅模式。

📖 小节

📝 作业

  1. 为银行账户系统添加 FixedDepositAccount 类,设定固定存期,到期前取款收取违约金
  2. 为图形面积计算器添加 Triangle 类,实现面积计算并参与排序
  3. 为库存管理系统添加 Purchase 事件,在每次添加商品时触发,记录采购日志
Web-Tutorial.com

Web-Tutorial 技术团队

由多位开发者共同维护的编程教程平台。每篇教程由对应领域的开发者编写和审核,确保内容准确可靠。如发现任何问题,欢迎向我们反馈。

100%

🙏 帮我们做得更好

我们是刚上线的编程教程站,几个人的小团队,精力有限。页面虽经检查,难免还有疏漏——链接失效、排版错乱、内容有误、语言生硬……

如果您发现了,麻烦告诉我们,我们会在收到反馈后第一时间进行修复,再次感谢您的光临 🙏