c# 面向對象/繼承關係設計

繼承
RTTIgit

RTTI

概念 RTTI(Run Time Type Identification)即經過運行時類型識別,程序可以使用基類的指針或引用來檢查着這些指針或引用所指的對象的實際派生類型。

相關資源

C#高級編程(第11版) Professional C# 7 and .NET Core 2.0github

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.c#

ObjectOrientation 章節中有介紹,ide

可是有些內容沒有細講, 好比純虛函數的子類如何 在全局變量聲明,如何在函數中定義,使用函數


c#spa

父類,子類指針

1.VirtualMethods

// fish  tail, lungs
// humam  limbs(arms and legs), lungs
// bird wings, lungs
//


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( ) // must  override
        {
             WriteLine($"Human: moves with legs   (using limbs when baby age)");  
        }

}


public class Kingkong: Organisms
{
        public Human()
            : base() { }

        public override void Move( ) // must  override
        {
             WriteLine($"Kingkong: moves with limbs");  
        }

}


public class Fish: Organisms
{
        public Fish()
            : base() { }

         public override void Move( ) // must  override
        {
             WriteLine($"Fish: moves with wings and tail");  
        }
}

public class Horse: Organisms //horse  zebra
{
        public Horse()
            : base() { }

        public override void Move( ) // must  override
        {
             WriteLine($"Horse: moves with legs");  
        }
}
using System;

namespace VirtualMethods
{
    class Program
    {
        //var _obj = null;  //var 沒法在全局變量 聲明
        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();//父類有abstract function. 全部子類函數必須override,
         }
         
        static void FuncA()
        {
            Fish fish = _Obj as Fish;//利用全局變量 _Obj
            fish.age = 1;
            fish.GetAge();
            fish.Move();
        }
       
    }
}

2.InheritanceWithConstructors

//Shape.cs
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}");
        }
    }
}
//ConcreteShapes.cs

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( )//只有Rectangle 纔有的函數,其餘類沒有聲明和實現
        {
             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) { }
    }
}
//Program.cs

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();//若是_sharp 是全局變量, 讓其餘地方也可以使用此對象 怎麼辦?
        }
        public staic void FuncA()
        {
          Rectangle rect= _sharp as Rectangle;
          rect.PrintRectangleFuncA(); //只有Rectangle 纔有的函數,其餘類沒有聲明和實現,能夠這樣調用
        }

        public static void DrawShape(Shape shape) => shape.Draw();
    }
}

3.UsingInterfaces

//基本上和VirtualMethods 相似,可是全部接口類的 子類, 要通用, 子類必須code

//IBankAccount.cs
namespace Wrox.ProCSharp
{
    public interface IBankAccount
    {
        void PayIn(decimal amount);//子類必須有實現
        bool Withdraw(decimal amount);//子類必須有實現
        decimal Balance { get; }//子類必須有實現
    }
}
//ITransferBankAccount.cs
namespace Wrox.ProCSharp
{
    public interface ITransferBankAccount : IBankAccount
    {
        bool TransferTo(IBankAccount destination, decimal amount);
    }
}
//JupiterBank.cs

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)//Withdraw撤回
        {
            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}";
    }
}
//VenusBank.cs

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}";
    }
}
//Program.cs
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();//用子類去new
        }

        public static void FunA()
        {
            if(_golbal_obj!=null)
            {
               _golbal_obj.PayIn(100);//直接調用SaverAccount 子類的 實現,因此這也是爲何須要子類所有都要實現,
               _golbal_obj.Withdraw(100);//直接調用SaverAccount 子類的 實現
            }   
        }
        
                

    }
}
相關文章
相關標籤/搜索