1. 程式人生 > >C#多型的實現:虛方法、抽象類、介面

C#多型的實現:虛方法、抽象類、介面

一、多型的概念

        多型簡單講就是一個類針對同一個方法可以表現出多種不同的形態。舉例:動物類有個叫的方法,通過多型當呼叫動物類叫的方法時,根據動物類物件實際存放子物件的不同,則表現出不同的叫聲,有可能是人叫、也有可能是狗叫、也有可能是貓叫等等。

二、多型的實現

(1)虛方法

          步驟:①將父類的方法標記為虛方法,即給父類的方法加上virtual修飾

                     ②在子類中重寫父類的方法,即給子類對應的方法加上override修飾

          注意:①在虛方法中父類可以建立例項

                     ②父類的方法有實現並且可以被呼叫

                     ③子類可以重寫父類的方法也可以不重寫,重寫的實現多型,不重寫的不能實現多型  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace 虛方法
{
    class Program
    {
        static void Main(string[] args)
        {
            Employee emp = new Employee();
            Manager mg = new Manager();
            Programmer pm = new Programmer();
            Employee[] emps = { emp, mg, pm };
            for (int i = 0; i < emps.Length; i++)
            {
                emps[i].DaKa();
            }
            Console.ReadKey();
        }
    }
 
    public class Employee  //基類(父類)
    {
        public virtual void DaKa()
        {
            Console.WriteLine("9點打卡");
        }
    }
 
    public class Manager : Employee
    {
        public override void DaKa()
        {
            Console.WriteLine("經理11點打卡");
        }
    }
 
    public class Programmer : Employee
    {
        public override void DaKa()
        {
            Console.WriteLine("程式猿不打卡");
        }
    }
 
}

(2)抽象類

          步驟:①將父類標記為抽象類、將父類的方法標記為抽象方法,即給父類和父類的方法加上abstract修飾

                     ②在子類中重寫父類的方法,即給子類對應的方法加上override修飾

          注意:①在建立父類例項時不能使用new父類名(),而應該是new子類名()

                     ②抽象成員必須標記為abstract,並且不能有任何實現

                     ③子類繼承抽象類後,必須把父類中的所有抽象成員都重寫,除非子類也是一個抽象類,則可以不重寫

                     ④如果父類的抽象方法中有引數,那麼繼承這個抽象父類的子類在重寫父類的方法的時候必須傳入對應的引數

                     ⑤如果抽象父類的抽象方法中有返回值,那麼子類在重寫這個抽象方法的時候也必須要傳入返回值  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace 抽象類
{
    class Program
    {
        static void Main(string[] args)
        {
            //題目:使用多型求矩形的面積和周長以及圓形的面積和周長
            Shape shape = new Square(5, 6); //new Circle(5);
            double area = shape.GetArea();
            double perimeter = shape.GetPerimeter();
            Console.WriteLine("這個形狀的面積是{0},周長是{1}", area, perimeter);
            Console.ReadKey();
        }
    }
 
    public abstract class Shape
    {
        public abstract double GetArea();
        public abstract double GetPerimeter();
    }
    public class Circle : Shape
    {
 
        private double _r;
        public double R
        {
            get { return _r; }
            set { _r = value; }
        }
 
        public Circle(double r)
        {
            this.R = r;
        }
        public override double GetArea()
        {
            return Math.PI * this.R * this.R;
        }
 
        public override double GetPerimeter()
        {
            return 2 * Math.PI * this.R;
        }
    }
    public class Square : Shape
    {
        private double _height;
 
        public double Height
        {
            get { return _height; }
            set { _height = value; }
        }
 
        private double _width;
 
        public double Width
        {
            get { return _width; }
            set { _width = value; }
        }
 
        public Square(double height, double width)
        {
            this.Height = height;
            this.Width = width;
        }
 
        public override double GetArea()
        {
            return this.Height * this.Width;
        }
 
        public override double GetPerimeter()
        {
            return (this.Height + this.Width) * 2;
        }
    }
 
}

3)介面

          介面語法格式:

             [public] interface I..able    //命名一般以I開頭,以able結尾, I..able表示具備什麼能力

             {

     成員;

             }

          注意:①介面中的成員不允許新增訪問修飾符預設就是Public,普通類中的成員不加訪問修飾符的話預設是Private。

                     ②介面中的方法不允許有方法體

                     ③介面中的成員可以是方法、屬性、索引器,但不能為欄位和建構函式

                     ④介面不能被例項化,也就是說,介面不能new(不能建立物件)

                     ⑤實現介面的子類必須實現該介面的全部成員

                     ⑥介面與介面之間可以繼承,並且可以多繼承

                     ⑦一個類可以同時繼承一個類並實現多個介面,如果一個子類同時繼承了父類A,並實現了介面IA,那麼語法上A必須寫在IA的前面。classMyClass:A,IA{},因為類是單繼承的。  

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
 
namespace 介面
{
    class Program
    {
        static void Main(string[] args)
        {
            IFlyable birdFly = new Bird();
            birdFly.Fly(); //鳥在飛
            IFlyable personFly = new Person();
            personFly.Fly(); //人在飛 
            Console.ReadKey();
        }
    }
    public interface IFlyable
    {
        void Fly();
    }
 
    public class Bird : IFlyable
    {
        public void Fly()
        {
            Console.WriteLine("我是小鳥,我可以自由飛翔!");
        }
    }
 
    public class Person : IFlyable
    {
        public void Fly()
        {
            Console.WriteLine("我是超人,我要保護地球!");
        }
    }
 
}

(4)隱式實現介面和顯示實現介面的區別            區別:隱示實現介面和類都可以訪問,顯示實現只有介面可以訪問            顯示實現的好處:①隱藏程式碼的實現

                                         ②在使用介面訪問的系統中,呼叫者只能通過介面呼叫而不是底層的類來訪問  

    public interface IFlyable
    {
        void Fly();
    }
 
    public class Bird : IFlyable
    {
        public void Fly()
        {
            Console.WriteLine("我是小鳥,我可以自由飛翔!");
        }
    }

上面是隱式實現介面,通過介面實現呼叫,程式碼為:IFlyable birdFly = new Bird();birdFly.Fly(); 通過類實現呼叫,程式碼為:Bird bird = new Bird();bird.Fly();

    public interface IFlyable
    {
        void Fly();
    }
 
    public class Bird : IFlyable
    {
        void IFlyable.Fly()
        {
            Console.WriteLine("我是小鳥,我可以自由飛翔!");
        }
    }