VB.net 2010 视频教程 VB.net 2010 视频教程 python基础视频教程
SQL Server 2008 视频教程 c#入门经典教程 Visual Basic从门到精通视频教程
当前位置:
首页 > 编程开发 > c#编程 >
  • 继承与多态——用C#开发动物分类与行为模拟

第一部分:C#基础入门
实例2:继承与多态——动物分类与行为模拟
实例介绍
继承与多态是面向对象编程的两大核心特性:继承让子类复用父类的属性和方法,避免重复代码;多态让不同子类对象通过统一的父类接口执行各自的实现,提升代码灵活性。本实例通过模拟动物分类(如狗、猫、鸟)及其行为(叫、移动),让你掌握抽象类、虚方法、重写、多态的核心用法,理解“如何用代码描述类的层级关系与动态行为”。
需求分析
1.定义父类:抽象类Animal,包含所有动物共有的属性(名字、年龄)和抽象方法(叫、移动);
2.定义子类:Dog、Cat、Bird继承自Animal,重写父类的抽象方法,实现各自的行为;
3.多态应用:用父类类型的容器存储不同子类对象,统一调用方法,自动执行子类的实现;
4.行为展示:输出每种动物的名字、年龄及对应的行为(如“旺财:汪汪汪”“咪咪:喵喵喵”);
5.扩展性:新增子类(如Fish)时无需修改现有代码,体现开vb.net教程C#教程python教程SQL教程access 2010教程放封闭原则。
代码实现
csharp

	using System;
	using System.Collections.Generic;
	
	namespace InheritanceAndPolymorphismDemo
	{
	// 1. 抽象父类:所有动物的基类(无法实例化,只能被继承)
	public abstract class Animal
	{
	// 公共属性:所有动物共有的特征
	public string Name { get; set; }
	public int Age { get; set; }
	
	// 构造函数:初始化父类属性
	public Animal(string name, int age)
	{
	Name = name;
	Age = age;
	}
	
	// 抽象方法:所有动物必须实现的行为(无具体实现)
	public abstract string MakeSound();
	public abstract string Move();
	}
	
	// 2. 子类:狗(继承Animal,重写抽象方法)
	public class Dog : Animal
	{
	// 构造函数:调用父类构造函数初始化名字和年龄
	public Dog(string name, int age) : base(name, age) { }
	
	// 重写抽象方法:狗的叫声
	public override string MakeSound() => $"{Name}:汪汪汪~";
	// 重写抽象方法:狗的移动方式
	public override string Move() => $"{Name}:四条腿跑~";
	}
	
	// 3. 子类:猫(继承Animal,重写抽象方法)
	public class Cat : Animal
	{
	public Cat(string name, int age) : base(name, age) { }
	public override string MakeSound() => $"{Name}:喵喵喵~";
	public override string Move() => $"{Name}:轻步走~";
	}
	
	// 4. 子类:鸟(继承Animal,重写抽象方法)
	public class Bird : Animal
	{
	public Bird(string name, int age) : base(name, age) { }
	public override string MakeSound() => $"{Name}:叽叽叽~";
	public override string Move() => $"{Name}:展翅飞~";
	}
	
	// 5. 动物管理器:统一处理不同动物的行为(体现多态)
	public static class AnimalManager
	{
	// 多态方法:接收Animal类型参数,自动调用子类实现
	public static void ShowAnimalBehavior(Animal animal)
	{
	Console.WriteLine($"【{animal.Name}】年龄:{animal.Age}岁");
	Console.WriteLine(animal.MakeSound());
	Console.WriteLine(animal.Move());
	Console.WriteLine("------------------------");
	}
	}
	
	// 6. 主程序:模拟动物行为
	class Program
	{
	static void Main(string[] args)
	{
	// 用父类类型的列表存储不同子类对象(多态的核心体现)
	List<Animal> animals = new List<Animal>
	{
	new Dog("旺财", 3),
	new Cat("咪咪", 2),
	new Bird("小麻雀", 1)
	};
	
	Console.WriteLine("=== 动物行为模拟 ===");
	foreach (var animal in animals)
	{
	AnimalManager.ShowAnimalBehavior(animal);
	}
	}
	}
	}

逐行讲解

  1. 抽象父类Animal的设计
    csharp
	public abstract class Animal
	{
	public string Name { get; set; }
	public int Age { get; set; }
	public abstract string MakeSound();
	}

abstract关键字:标记类为抽象类,意味着它不能被实例化(不能new Animal()),只能作为父类被继承;
抽象方法:MakeSound()和Move()无具体实现(没有方法体),子类必须重写这些方法,否则编译报错;
公共属性:Name和Age是所有动物共有的特征,子类直接继承,无需重复定义。
2. 子类Dog的继承与重写
csharp

	public class Dog : Animal
	{
	public Dog(string name, int age) : base(name, age) { }
	public override string MakeSound() => $"{Name}:汪汪汪~";
	}

继承语法:class Dog : Animal表示Dog类继承自Animal类;
base关键字:构造函数中base(name, age)调用父类的构造函数,初始化父类的Name和Age属性;
override关键字:标记方法为重写父类的抽象方法,实现狗的具体叫声——这是多态的基础。
3. 多态的体现(AnimalManager类)
csharp

	public static void ShowAnimalBehavior(Animal animal)
	{
	Console.WriteLine(animal.MakeSound());
	}

父类类型参数:方法参数是Animal类型,但实际传入的是Dog、Cat、Bird等子类对象;
动态绑定:调用animal.MakeSound()时,程序会根据对象的实际类型(而非变量类型)执行对应的子类方法——比如传入Dog对象就执行Dog的MakeSound,传入Cat就执行Cat的,这就是多态!
4. 主程序的多态应用
csharp

	List<Animal> animals = new List<Animal> { new Dog("旺财",3), new Cat("咪咪",2) };
	foreach (var animal in animals) AnimalManager.ShowAnimalBehavior(animal);

父类容器存储子类对象:用Animal类型的列表存储不同子类对象,体现“向上转型”(子类对象可以赋值给父类变量);
统一调用:循环中调用ShowAnimalBehavior方法,无需区分动物类型,自动执行各自的行为——这大大简化了代码,新增子类时只需继承Animal,无需修改现有逻辑。
基础知识拓展

  1. 抽象类vs接口的核心区别
    | 特性 | 抽象类(Abstract Class) | 接口(Interface) |
    | ---- | ---- | ---- |
    | 继承关系 | 单继承(子类只能继承一个抽象类) | 多实现(类可以实现多个接口) |
    | 成员类型 | 可包含字段、属性、抽象方法、非抽象方法 | 只能包含抽象方法、属性(C#8+支持默认实现) |
    | 设计目的 | 表示“is-a”关系(如Dog is an Animal) | 表示“has-a”关系(如Dog has a Flyable能力) |
    | 实例化 | 不能实例化 | 不能实例化 |

选择建议:如果类之间有明显的层级关系(如动物分类),用抽象类;如果需要给不同类添加相同的行为(如飞行、游泳),用接口。
2. 重写(Override)vs隐藏(New)
重写:用override关键字,子类方法覆盖父类方法,调用时看对象实际类型(多态);
隐藏:用new关键字,子类方法隐藏父类方法,调用时看变量类型(非多态);
示例:
csharp

	Animal a = new Dog("旺财",3);
	a.MakeSound(); // 调用Dog的方法(重写)
	Dog d = new Dog("旺财",3);
	d.MakeSound(); // 调用Dog的方法
	Animal a2 = new Animal(); // 错误:抽象类不能实例化
  1. 多态的实现原理(虚方法表)
    C#中多态通过虚方法表(VMT)实现:
    每个包含虚方法(或抽象方法)的类都有一个VMT,存储该类所有虚方法的地址;
    子类重写方法时,会替换VMT中对应方法的地址为子类方法的地址;
    调用虚方法时,程序会先查找对象的VMT,找到对应的方法地址执行——这就是动态绑定的本质。
    扩展思考
    1.新增子类:添加Fish类,继承Animal,重写MakeSound(“泡泡泡”)和Move(“游”),看看主程序是否需要修改?
    2.接口替代抽象类:定义IAnimal接口,包含MakeSound和Move方法,让Dog、Cat等实现该接口,对比和抽象类的区别;
    3.多态的其他场景:实现动物的“进食”行为,不同动物吃不同食物(如狗吃肉、猫吃鱼),用多态统一处理;
    4.虚方法的应用:将Animal的MakeSound改为虚方法(非抽象),提供默认实现,让子类可选重写——这适合部分动物有默认行为的场景。
    总结
    继承与多态是面向对象编程的“灵魂”:
    继承帮你复用代码,减少重复劳动(子类不用再写Name和Age属性);
    多态让你用统一的方式处理不同对象,提升代码的灵活性和扩展性(新增动物只需加子类,无需改现有逻辑);
    抽象类+重写是实现多态的常用方式,核心是“父类定义接口,子类实现细节”。
    掌握这两个特性,你就能写出更简洁、更易维护的代码,为后续学习设计模式打下坚实基础!

本站原创,转载请注明出处:https://www.xin3721.com/ArticlecSharp/c49403.html


相关教程