淺談C#中重寫和隱藏的區別

孤舟寒江發表於2024-04-23

重寫

派生類與基類中方法名、返回引數型別、引數個數均一致,就稱派生類重寫了基類中的方法。

using System;
using System.Collections.Generic;

namespace Day0
{
    class Program
    {
        static void Main(string[] args)
        {
            Transport transport = new Transport();
            Car car = new Car();
            Bicycle bicycle = new Bicycle();

            transport.Drive();
            transport.Refuel();
            Console.WriteLine("transport oil = "+transport.oil);
            Console.WriteLine("==============");
            transport = car;
            transport.Drive();
            transport.Refuel();
            Console.WriteLine("transport oil = " + transport.oil);
            car.Drive();
            car.Refuel();
            Console.WriteLine("transport oil = " + transport.oil);
            Console.WriteLine("car oil = " + car.oil);
            Console.WriteLine("==============");
            transport = bicycle;
            transport.Drive();
            transport.Refuel();
            Console.WriteLine("transport oil = " + transport.oil);
            bicycle.Drive();
            bicycle.Refuel();
            Console.WriteLine("transport oil = " + transport.oil);
            Console.WriteLine("bicyle oil = " + bicycle.oil);

        }
    }
    class Transport
    {
        public int oil = 100;
        public virtual void Drive()
        {
            Console.WriteLine("駕駛交通工具...");
            oil -= 20;
        }
        public void Refuel()
        {
            Console.WriteLine("預設加註燃料");
            oil += 20;
        }

    }
    class Car : Transport
    {
        public override void Drive()
        {
            oil -= 30;
            Console.WriteLine("駕駛小轎車...");
        }
        public new void Refuel()
        {
            oil += 30;
            Console.WriteLine("小汽車加註燃料");
        }
    }
    class Bicycle : Transport
    {
        public override void Drive()
        {
            oil -= 0;
            Console.WriteLine("騎腳踏車...");
        }
        public new void Refuel()
        {
            oil += 0;
            Console.WriteLine("腳踏車加註燃料");
        }
    }

}

  執行結果

可以看出重寫是多型的,當我們呼叫Drive方法時候,子類方法是覆蓋掉父類中的方法的;而對於隱藏父類方法並不會被覆蓋。

歸其原因,重寫是子類方法表新增新的記錄,執行時修改父級方法表中地址,所以transport 是因為Drive方法地址被修改了出現多型。(動態繫結)

而隱藏僅僅是在子類方法表中新增新的記錄,子型別引用呼叫子型別方法(Refuel),父型別引用呼叫父類Refuel方法(靜態繫結)編譯時便確定。

相關文章