文章目录
- 多态
- [一、virtual、override 和 base 关键字](#一、virtual、override 和 base 关键字)
-
- [1、**`virtual` 关键字** (虚方法)](#1、
virtual
关键字 (虚方法)) - [2、**`override` 关键字** (重写)](#2、
override
关键字 (重写)) - [3、**`base` 关键字** (基类访问)](#3、
base
关键字 (基类访问)) - 4、总结:
- [1、**`virtual` 关键字** (虚方法)](#1、
- 二、抽象类和抽象方法
-
- 1、抽象类
-
- [1.1 什么是抽象类](#1.1 什么是抽象类)
- [1.2 定义和使用抽象类](#1.2 定义和使用抽象类)
- 2、抽象方法
-
- [2.1 什么是抽象方法](#2.1 什么是抽象方法)
- [2.2 定义和使用抽象方法](#2.2 定义和使用抽象方法)
- 3、抽象类和抽象方法的特点
- 4、使用抽象类和抽象方法的优势
- 5、小结
- 专栏推荐
- 完结
多态
C# 中的 多态 是面向对象编程中的一个重要特性,允许对象以不同的方式表现出来。通过多态,同一个方法可以根据对象的不同类型而表现出不同的行为。C# 主要通过 方法重载(Overloading)、方法重写(Overriding)和 接口实现 来实现多态。
多态的主要类型
- 编译时多态 (
静态多态
)通过方法重载和运算符重载实现,在编译时就能确定调用哪个方法。 - 运行时多态 (
动态多态
)通过方法重写和接口实现实现,方法的调用是在运行时根据对象的实际类型来决定的。
编译时多态我们已经学过了,就不重复讲了。
一、virtual、override 和 base 关键字
1、virtual
关键字 (虚方法)
virtual
关键字用于在基类中声明一个方法为虚方法。虚方法允许子类在继承时对该方法进行重写(通过 override
),从而实现多态。
- 继承:虚方法通常是在基类中定义的,子类可以继承并对其进行重写。
- 多态:虚方法支持运行时多态,允许在运行时根据对象的实际类型来调用正确的实现。
示例:
csharp
public class Animal
{
// 基类中的虚方法
public virtual void Speak()
{
Console.WriteLine("Animal speaks");
}
}
public class Dog : Animal
{
// 重写基类中的虚方法
public override void Speak()
{
Console.WriteLine("Dog barks");
}
}
class Program
{
static void Main()
{
Animal animal = new Animal();
animal.Speak(); // 输出: Animal speaks
Dog dog = new Dog();
dog.Speak(); // 输出: Dog barks
// 多态示例
Animal animalDog = new Dog();
animalDog.Speak(); // 输出: Dog barks
}
}
virtual
的作用:
virtual
声明基类中的方法为虚方法,子类可以选择是否重写它。- 通过虚方法和重写(
override
),我们实现了 多态。
2、override
关键字 (重写)
override
关键字用于在子类中重写基类中的虚方法。它实现了多态机制,允许子类提供不同于基类的具体实现。
- 继承 :
override
是在子类中对基类方法的实现。 - 多态 :通过
override
,子类改变了基类方法的行为,并且这种改变支持运行时多态。
示例:
csharp
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Animal speaks");
}
}
public class Dog : Animal
{
public override void Speak() // 重写基类的虚方法
{
Console.WriteLine("Dog barks");
}
}
class Program
{
static void Main()
{
Animal animal = new Dog();
animal.Speak(); // 输出: Dog barks (运行时多态)
}
}
override
的作用:
override
用于子类中修改继承自基类的虚方法的行为,确保多态性。- 它是 多态 实现的一部分,使得在运行时能够调用到正确的方法实现。
3、base
关键字 (基类访问)
base
关键字用于在子类中访问基类的成员(如方法、构造函数等)。在方法重写中,base
可以用于调用基类的方法,通常是在子类重写方法时需要保留基类的一些逻辑。
- 继承 :
base
允许子类访问基类的方法或字段,这是继承中的一种常见需求。 - 多态 :虽然
base
本身不直接表示多态,但它通常在重写方法时与多态一起使用,确保子类能够在需要时调用基类的方法。
示例:
csharp
public class Animal
{
public virtual void Speak()
{
Console.WriteLine("Animal speaks");
}
}
public class Dog : Animal
{
public override void Speak()
{
base.Speak(); // 调用基类的 Speak 方法
Console.WriteLine("Dog barks");
}
}
class Program
{
static void Main()
{
Animal animal = new Dog();
animal.Speak();
}
}
base
的作用:
base
允许子类在重写方法时调用基类的方法,这通常用于在重写时保留基类的行为。- 它本身不直接影响多态性,但它可以与多态一起使用,以确保基类方法能够在子类中被访问。
4、总结:
virtual
关键字与 继承 相关,允许基类中的方法在子类中被重写,从而为 多态 打下基础。override
关键字用于在子类中重写基类中的虚方法,是实现 多态 的关键。base
关键字用于子类访问基类的成员,它与 继承 关系更为紧密,但在重写方法时也常常与 多态 结合使用。
二、抽象类和抽象方法
在 C# 中,抽象类 和抽象方法(函数)是面向对象编程中的核心概念,旨在提供一种模板或基础结构,供子类继承并实现细节。它们在定义类的层次结构和实现多态性方面发挥着重要作用。
1、抽象类
1.1 什么是抽象类
抽象类是不能实例化的类,它提供了一个通用的类模板,不能直接创建其对象。抽象类可以包含抽象方法和普通方法,也可以包含字段和属性。
- 抽象类通常是作为基类(父类)来提供子类继承。
- 抽象类可以包含 抽象方法 (没有方法体,需要由子类实现),也可以包含 具体方法(已经实现的方法,子类可以直接使用或重写)。
1.2 定义和使用抽象类
- 抽象类使用
abstract
关键字声明。 - 抽象类可以有构造函数,但不能直接实例化。
csharp
using System;
abstract class Animal
{
public string Name { get; set; }
// 抽象方法:没有实现,要求子类必须实现
public abstract void Speak();
// 普通方法:可以直接使用或重写
public void Eat()
{
Console.WriteLine($"{Name} is eating.");
}
}
class Dog : Animal
{
public Dog(string name)
{
Name = name;
}
// 必须实现抽象方法
public override void Speak()
{
Console.WriteLine($"{Name} barks.");
}
}
class Program
{
static void Main()
{
// Animal animal = new Animal(); // 错误,不能直接实例化抽象类
Dog dog = new Dog("Buddy");
dog.Speak(); // 输出:Buddy barks.
dog.Eat(); // 输出:Buddy is eating.
}
}
在这个例子中,Animal
是一个抽象类,它包含一个抽象方法 Speak
和一个普通方法 Eat
。类 Dog
继承自 Animal
并实现了 Speak
方法。
2、抽象方法
2.1 什么是抽象方法
抽象方法是没有实现的方法,只有方法签名。它们必须在抽象类中定义,并且在任何非抽象的子类中实现。抽象方法提供了一个接口或契约,要求派生类必须提供该方法的具体实现。
- 抽象方法使用
abstract
关键字声明。 - 抽象方法不能包含方法体,只有方法签名。
- 抽象方法必须在子类中重写(通过
override
关键字实现)。
2.2 定义和使用抽象方法
csharp
abstract class Shape
{
// 抽象方法:每个子类需要实现自己的计算面积方法
public abstract double Area();
}
class Circle : Shape
{
public double Radius { get; set; }
public Circle(double radius)
{
Radius = radius;
}
// 实现抽象方法
public override double Area()
{
return Math.PI * Radius * Radius;
}
}
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;
}
}
class Program
{
static void Main()
{
Shape circle = new Circle(5);
Shape rectangle = new Rectangle(10, 20);
Console.WriteLine($"Circle Area: {circle.Area()}");
Console.WriteLine($"Rectangle Area: {rectangle.Area()}");
}
}
在这个例子中,Shape
是一个抽象类,包含一个抽象方法 Area
,它在 Circle
和 Rectangle
类中被具体实现。这是一个常见的场景:抽象类提供了一个通用的接口(如 Area
),具体的计算方法由子类来实现。
3、抽象类和抽象方法的特点
-
抽象类不能实例化:不能直接创建抽象类的对象,必须通过子类来实例化。
-
抽象方法没有方法体:抽象方法只定义方法签名,子类必须提供实现。
-
可以包含普通方法:抽象类除了抽象方法外,还可以包含已经实现的普通方法、字段、属性和构造函数。
-
子类实现抽象方法:任何继承抽象类的子类,必须实现所有的抽象方法,否则该子类也必须被声明为抽象类。
-
构造函数:抽象类可以有构造函数,可以在子类中调用基类构造函数来初始化。
-
多态性:通过抽象类和抽象方法,可以在子类中提供不同的实现方式,利用多态性让代码更加灵活。
4、使用抽象类和抽象方法的优势
- 代码复用:抽象类允许在基类中实现一些公共的功能或模板方法,避免重复代码。
- 强制实现契约:通过抽象方法,确保所有子类都遵守同一个方法签名和行为规范,保证了接口的一致性。
- 多态性:抽象类提供了通过基类引用调用子类实现的多态性,使得代码更加灵活和扩展性更强。
5、小结
- 抽象类 是一个不能实例化的类,它提供了一个通用的模板,供其他类继承。
- 抽象方法 是没有方法体的方法,它定义了一个接口,强制派生类实现具体的功能。
- 抽象类和抽象方法是面向对象设计中非常重要的工具,能够提高代码的可维护性和可扩展性。
专栏推荐
地址 |
---|
【从零开始入门unity游戏开发之------C#篇】 |
【从零开始入门unity游戏开发之------unity篇】 |
【制作100个Unity游戏】 |
【推荐100个unity插件】 |
【实现100个unity特效】 |
【unity框架开发】 |
完结
赠人玫瑰,手有余香!如果文章内容对你有所帮助,请不要吝啬你的点赞评论和关注
,你的每一次支持
都是我不断创作的最大动力。当然如果你发现了文章中存在错误
或者有更好的解决方法
,也欢迎评论私信告诉我哦!
好了,我是向宇
,https://xiangyu.blog.csdn.net
一位在小公司默默奋斗的开发者,闲暇之余,边学习边记录分享,站在巨人的肩膀上,通过学习前辈们的经验总是会给我很多帮助和启发!如果你遇到任何问题,也欢迎你评论私信或者加群找我, 虽然有些问题我也不一定会,但是我会查阅各方资料,争取给出最好的建议,希望可以帮助更多想学编程的人,共勉~