0.2多态性继承,接口

 多态性-单一职责原则(Weapon,Player)封装,只暴露了必要的接口

  1. 静态类型(Static Type): 静态类型是在编译时已知的,它是在代码编写时指定的变量类型。在您的代码中,currentWeapon 的静态类型是 Weapon,因为我们声明它为 Weapon 类型的变量。这意味着在编译时,编译器知道 currentWeapon 是一个 Weapon 对象。

  2. 动态类型(Dynamic Type): 动态类型是在运行时实际引用的对象的类型。在运行时,变量可以引用不同类型的对象,这就是多态性的体现。在您的代码中,currentWeapon 的动态类型可以是 PistolShotgunSubmachineGun 中的任何一个,具体取决于您在运行时将哪种类型的武器分配给它。

  3. 我们创建了一个 SubmachineGun 类的实例,并将其分配给了 smg 变量。在编译时,smg 的静态类型仍然是 Weapon,但在运行时,它引用了 SubmachineGun 的实例,因此它的动态类型是 SubmachineGun

    当调用 player.UseWeapon() 时,currentWeapon 的动态类型(在这种情况下是 SubmachineGun)决定了哪个 Fire 方法将被调用。这正是多态性的概念:相同的方法调用可以根据实际引用的对象的类型而具有不同的行为。所以,尽管 currentWeapon 的静态类型是 Weapon,但在运行时,它引用了 SubmachineGun 的实例,因此调用的是 SubmachineGun 类中的 Fire 方法。

    这就是为什么在 player.UseWeapon() 中能够使用 SubmachineGun 中的 Fire 方法的原因。多态性允许我们根据实际对象的类型来调用适当的方法,而不受静态类型的限制。

 class Weapon
    {
        public string Name { get; set; }
        public Weapon(string name)
        {
            Name = name;
        }

        public virtual void Fire()
        {
            Console.WriteLine($"使用了{Name}开火~~~~");

        }

        class Pistol : Weapon
        {
            public Pistol() : base("Pistol")
            {
            }
        }
        class Shotgun : Weapon
        {
            public Shotgun() : base("Shotgun")
            { }
        }
        class SubmachineGun : Weapon
        {
            public SubmachineGun() : base("SubmachineGun")
            {
            }

            public override void Fire()
            {
                Console.WriteLine("Firiiiiiiiiiiinnnnnnngggggggggggggg the motherfuck");

            }
        }
        class Player
        {
            private Weapon currentWeapon;
            public Player()
            {
                currentWeapon = new Pistol();

            }

            public void PickUpWeapon(Weapon newWeapon)
            {
                Console.WriteLine($"你拾取了新武器{newWeapon}");
                currentWeapon = newWeapon;

            }

            public void UseWeapon()
            {
                currentWeapon.Fire();
            }

        }

        class Program
    {
        static void Main(string[] args)
        {
                Player player = new Player();
                player.UseWeapon();

                Weapon smg = new SubmachineGun();
                player.PickUpWeapon( smg );
                player.UseWeapon();

                Weapon shotgun = new Shotgun();
                player.PickUpWeapon(shotgun);
                player.UseWeapon();
        }

/* 还可以这样使用
SubmachineGun submachineGun = new SubmachineGun();
submachineGun.SpecialMethod(); // 调用 SubmachineGun 类中的特有方法

// 或者
if (weapon is SubmachineGun submachineGun)
{
    submachineGun.SpecialMethod(); // 调用 SubmachineGun 类中的特有方法
}
*/

 接口演示来实现相同的功能

using System;

// 武器接口
public interface IWeapon
{
    void Fire();
}

// 不同类型的武器实现接口
public class SubmachineGun : IWeapon
{
    public void Fire()
    {
        Console.WriteLine("使用冲锋枪开火!");
    }
}

public class Shotgun : IWeapon
{
    public void Fire()
    {
        Console.WriteLine("使用散弹枪开火!");
    }
}

public class Pistol : IWeapon
{
    public void Fire()
    {
        Console.WriteLine("使用手枪开火!");
    }
}

// 玩家类
public class Player
{
    private IWeapon currentWeapon;

    public Player()
    {
        // 默认武器
        currentWeapon = new Pistol();
    }

    // 拾取武器并替换当前武器
    public void PickUpWeapon(IWeapon newWeapon)
    {
        Console.WriteLine($"拾取了 {newWeapon.GetType().Name}");
        currentWeapon = newWeapon;
    }

    // 使用当前武器
    public void UseWeapon()
    {
        currentWeapon.Fire();
    }
}

class Program
{
    static void Main()
    {
        Player player = new Player();

        player.UseWeapon(); // 使用默认武器(手枪)

        IWeapon smg = new SubmachineGun();
        player.PickUpWeapon(smg); // 拾取冲锋枪
        player.UseWeapon(); // 使用冲锋枪

        IWeapon shotgun = new Shotgun();
        player.PickUpWeapon(shotgun); // 拾取散弹枪
        player.UseWeapon(); // 使用散弹枪
    }
}

第二个代码演示

class Shape
{
    public virtual double Area()
    {
        return 0;
    }
}

class Circle : Shape
{
    private double radius;

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

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

class Rectangle : Shape
{
    private double width;
    private double height;

    public Rectangle(double w, double h)
    {
        width = w;
        height = h;
    }

    public override double Area()
    {
        return width * height;
    }
}

class Program
{
    static void Main()
    {
        Shape shape1 = new Circle(5);
        Shape shape2 = new Rectangle(4, 6);

        Console.WriteLine($"形状1的面积:{shape1.Area()}");
        Console.WriteLine($"形状2的面积:{shape2.Area()}");
    }
}

优点缺点

使用接口的优点:

  1. 实现多继承: 接口允许一个类实现多个接口,这克服了一些编程语言(如C#和Java)不支持多重继承的限制。通过实现多个接口,一个类可以获得多个不同的行为。

  2. 松耦合: 接口提供了一种松耦合的方式来定义类之间的合同。类只需要遵循接口定义的方法,而不需要关心其他类的具体实现。这增强了代码的灵活性和可维护性。

  3. 代码重用: 接口允许多个类实现相同的接口,从而促进了代码重用。您可以在不修改现有代码的情况下添加新的实现类。

使用接口的缺点:

  1. 增加复杂性: 当一个类实现多个接口时,可能会增加类的复杂性,特别是当接口具有多个方法时。这可能会导致代码难以理解和维护。

  2. 过多的接口: 过多的接口可能导致类的实现变得冗长,增加了开发和维护的工作量。

使用多态性的优点:

  1. 灵活性: 多态性允许不同的对象以相同的接口进行操作,这增加了代码的灵活性。您可以根据实际对象的类型来调用适当的方法。

  2. 扩展性: 新的子类可以轻松地添加到应用程序中,而不会影响现有的代码。这使得应用程序更容易扩展。

  3. 代码简洁性: 多态性使得代码更具可读性和简洁性,因为它可以减少条件语句和分支。

使用多态性的缺点:

  1. 性能开销: 虽然多态性在设计上提供了灵活性,但在一些情况下可能会引入性能开销,特别是在运行时解析对象类型时。

  2. 复杂性: 当代码中存在大量的子类和多态性时,可能会增加代码的复杂性,使得程序难以维护和理解。

综上所述,使用接口和多态性都有其适用的场景和优点。通常,接口更适合定义合同和规范,以确保类遵循特定的接口。多态性则更适合在运行时根据实际对象类型来实现不同的行为。在实际编程中,通常需要根据具体需求和设计目标来决定何时使用接口、多态性或两者结合使用,以达到最佳的代码设计和架构

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值