继承
RTTI
RTTI
| 概念 RTTI(Run Time Type Identification)即通过运行时类型识别,程序能够使用基类的指针或引用来检查着这些指针或引用所指的对象的实际派生类型。 |
相关资源
C#高级编程(第11版) Professional C# 7 and .NET Core 2.0
For code comments and issues please check Professional C#'s GitHub Repository
Please check my blog csharp.christiannagel.com for additional information for topics covered in the book.
在ObjectOrientation 章节中有介绍,
但是有些内容没有细讲, 比如纯虚函数的子类如何 在全局变量声明,如何在函数中定义,使用
c#
父类,子类
1.VirtualMethods
| |
| |
| |
| |
| |
| |
| |
| public abstract class Organisms |
| { |
| public Int32 age{get;} |
| |
| public virtual void GetAge() |
| { |
| WriteLine($"moves with {limbs}"); |
| } |
| |
| public abstract void Move( ); |
| |
| } |
| |
| |
| public class Human: Organisms |
| { |
| public Human() |
| : base() { } |
| |
| public override void Move( ) |
| { |
| WriteLine($"Human: moves with legs (using limbs when baby age)"); |
| } |
| |
| } |
| |
| |
| public class Kingkong: Organisms |
| { |
| public Human() |
| : base() { } |
| |
| public override void Move( ) |
| { |
| WriteLine($"Kingkong: moves with limbs"); |
| } |
| |
| } |
| |
| |
| public class Fish: Organisms |
| { |
| public Fish() |
| : base() { } |
| |
| public override void Move( ) |
| { |
| WriteLine($"Fish: moves with wings and tail"); |
| } |
| } |
| |
| public class Horse: Organisms |
| { |
| public Horse() |
| : base() { } |
| |
| public override void Move( ) |
| { |
| WriteLine($"Horse: moves with legs"); |
| } |
| } |
| |
| |
| using System; |
| |
| namespace VirtualMethods |
| { |
| class Program |
| { |
| |
| Organisms _Obj =null; |
| |
| static void Main() |
| { |
| var obj = new Human(); |
| obj.age = 23; |
| obj.GetAge(); |
| obj.Move(); |
| |
| |
| |
| } |
| static void Init() |
| { |
| _Obj = new Fish(); |
| _Obj.age = 2; |
| _Obj.GetAge(); |
| _Obj.Move(); |
| } |
| |
| static void FuncA() |
| { |
| Fish fish = _Obj as Fish; |
| fish.age = 1; |
| fish.GetAge(); |
| fish.Move(); |
| } |
| |
| } |
| } |
| |
2.InheritanceWithConstructors
| |
| using System; |
| |
| namespace InheritanceWithConstructors |
| { |
| public class Position |
| { |
| public int X { get; set; } |
| public int Y { get; set; } |
| public override string ToString() => $"X: {X}, Y: {Y}"; |
| } |
| |
| public class Size |
| { |
| public int Width { get; set; } |
| public int Height { get; set; } |
| public override string ToString() => $"Width: {Width}, Height: {Height}"; |
| } |
| |
| public class Shape |
| { |
| public Shape(int width, int height, int x, int y) |
| { |
| Size = new Size { Width = width, Height = height }; |
| Position = new Position { X = x, Y = y }; |
| } |
| |
| public Position Position { get; } |
| public Size Size { get; } |
| |
| public virtual void Draw() => Console.WriteLine($"Shape with {Position} and {Size}"); |
| |
| public virtual void Move(Position newPosition) |
| { |
| Position.X = newPosition.X; |
| Position.Y = newPosition.Y; |
| Console.WriteLine($"moves to {Position}"); |
| } |
| } |
| } |
| |
| |
| |
| using System; |
| |
| namespace InheritanceWithConstructors |
| { |
| public class Rectangle : Shape |
| { |
| public Rectangle(int width, int height, int x, int y) |
| : base(width, height, x, y) { } |
| |
| public Rectangle() |
| : base(width: 0, height: 0, x: 0, y: 0) { } |
| |
| public override void Draw() => |
| Console.WriteLine($"Rectangle with {Position} and {Size}"); |
| |
| public override void Move(Position newPosition) |
| { |
| Console.Write("Rectangle "); |
| base.Move(newPosition); |
| } |
| |
| public void PrintRectangleFuncA( ) |
| { |
| Console.Write("Rectangle FuncA "); |
| } |
| } |
| |
| public class Ellipse : Shape |
| { |
| public Ellipse(int width, int height, int x, int y) |
| : base(width, height, x, y) { } |
| |
| public Ellipse() |
| : base(width: 0, height: 0, x: 0, y: 0) { } |
| } |
| } |
| |
| |
| namespace InheritanceWithConstructors |
| { |
| class Program |
| { |
| Shape _sharp = null; |
| static void Main(string[] args) |
| { |
| var r = new Rectangle(); |
| r.Position.X = 33; |
| r.Position.Y = 22; |
| r.Size.Width = 200; |
| r.Size.Height = 100; |
| r.Draw(); |
| DrawShape(r); |
| |
| r.Move(new Position { X = 120, Y = 40 }); |
| r.Draw(); |
| |
| Shape s1 = new Ellipse(); |
| DrawShape(s1); |
| } |
| public staic void Init() |
| { |
| _sharp = new Rectangle(); |
| } |
| public staic void FuncA() |
| { |
| Rectangle rect= _sharp as Rectangle; |
| rect.PrintRectangleFuncA(); |
| } |
| |
| public static void DrawShape(Shape shape) => shape.Draw(); |
| } |
| } |
| |
3.UsingInterfaces
//基本上和VirtualMethods 类似,但是所有接口类的 子类, 要通用, 子类必须
| |
| namespace Wrox.ProCSharp |
| { |
| public interface IBankAccount |
| { |
| void PayIn(decimal amount); |
| bool Withdraw(decimal amount); |
| decimal Balance { get; } |
| } |
| } |
| |
| |
| namespace Wrox.ProCSharp |
| { |
| public interface ITransferBankAccount : IBankAccount |
| { |
| bool TransferTo(IBankAccount destination, decimal amount); |
| } |
| } |
| |
| |
| |
| |
| using System; |
| |
| namespace Wrox.ProCSharp.JupiterBank |
| { |
| public class GoldAccount : IBankAccount |
| { |
| private decimal _balance; |
| |
| public void PayIn(decimal amount) => _balance += amount; |
| |
| public bool Withdraw(decimal amount) |
| { |
| if (_balance >= amount) |
| { |
| Console.WriteLine($"GoldAccount(IBankAccount): Withdraw(){_balance}"); |
| _balance -= amount; |
| return true; |
| } |
| Console.WriteLine("GoldAccount(IBankAccount): Withdraw attempt failed."); |
| return false; |
| } |
| |
| public decimal Balance => _balance; |
| |
| public override string ToString() => |
| $"GoldAccount(IBankAccount): Balance = {_balance,6:C}"; |
| } |
| |
| public class CurrentAccount : ITransferBankAccount |
| { |
| private decimal _balance; |
| |
| public void PayIn(decimal amount) => _balance += amount; |
| |
| public bool Withdraw(decimal amount) |
| { |
| if (_balance >= amount) |
| { |
| _balance -= amount; |
| return true; |
| } |
| Console.WriteLine("Withdrawal attempt failed."); |
| return false; |
| } |
| |
| public decimal Balance => _balance; |
| |
| public bool TransferTo(IBankAccount destination, decimal amount) |
| { |
| bool result = Withdraw(amount); |
| if (result) |
| { |
| destination.PayIn(amount); |
| } |
| return result; |
| } |
| |
| public override string ToString() => |
| $"Jupiter Bank Current Account: Balance = {_balance,6:C}"; |
| } |
| } |
| |
| |
| |
| using System; |
| |
| namespace Wrox.ProCSharp.VenusBank |
| { |
| public class SaverAccount : IBankAccount |
| { |
| private decimal _balance; |
| |
| public void PayIn(decimal amount) => _balance += amount; |
| |
| public bool Withdraw(decimal amount) |
| { |
| if (_balance >= amount) |
| { |
| _balance -= amount; |
| return true; |
| } |
| Console.WriteLine("Withdrawal attempt failed."); |
| return false; |
| } |
| |
| public decimal Balance => _balance; |
| |
| public override string ToString() => |
| $"Venus Bank Saver: Balance = {_balance,6:C}"; |
| } |
| } |
| |
| |
| namespace UsingInterfaces |
| { |
| class Program |
| { |
| IBankAccount _golbal_obj =null; |
| static void Main() |
| { |
| IBankAccount venusAccount = new SaverAccount(); |
| IBankAccount jupiterAccount = new GoldAccount(); |
| |
| venusAccount.PayIn(200); |
| venusAccount.Withdraw(100); |
| Console.WriteLine(venusAccount.ToString()); |
| |
| jupiterAccount.PayIn(500); |
| jupiterAccount.Withdraw(600); |
| jupiterAccount.Withdraw(100); |
| Console.WriteLine(jupiterAccount.ToString()); |
| |
| } |
| |
| public static void Init() |
| { |
| _golbal_obj = new SaverAccount(); |
| } |
| |
| public static void FunA() |
| { |
| if(_golbal_obj!=null) |
| { |
| _golbal_obj.PayIn(100); |
| _golbal_obj.Withdraw(100); |
| } |
| } |
| |
| |
| |
| } |
| } |
| |
| |
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· winform 绘制太阳,地球,月球 运作规律
· AI与.NET技术实操系列(五):向量存储与相似性搜索在 .NET 中的实现
· 超详细:普通电脑也行Windows部署deepseek R1训练数据并当服务器共享给他人
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 上周热点回顾(3.3-3.9)