實驗--抽象類的使用

iamzxf發表於2015-05-12

實驗內容:

1、深入理解多型的概念

2、掌握使用抽象類實現多型的方法

3、掌握虛方法和抽象方法的定義及使用

4、掌握方法的重寫及覆蓋

 

重點難點:

1、多型的概念;

2、抽象類實現多型的方法;

3、虛方法和抽象方法的定義及使用;

 

實驗內容:

1、 試編寫控制檯應用程式,完成下列要求:

(1)設計一個交通工具物件模型,定義一個車輛類Vehicle(抽象)

   具有編號、名稱、已行駛的路程;三個引數的建構函式。

   加速、轉向兩個抽象方法,加速方法輸入起始速度,返回加速後的速度,轉向方法無輸入引數,返回轉向時間(分鐘)

(2)定義Plane類繼承於Vehicle,具有屬性飛行的高度,Plane每次加速能使速度提高5倍,每次轉向需20分鐘;

(3)定義Car類繼承於Vehicle,Car每次加速能使速度提高1.5倍,每次轉向需1分鐘;

(4)定義Skoda類繼承於Car類,Skoda每次能使速度提高2倍。

(5)在main()函式中進行測試,定義一個車輛類Vehicle陣列,輸出每個物件的編號,名稱、已行駛的路程、速度和轉向時間。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication1
{
    abstract class  Vehicle
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public double Miles { get; set; }

        public Vehicle(string id, string name, double miles)
        {
            this.Id = id;
            this.Name = name;
            this.Miles = miles;
        }

        public abstract double Accelerate(double initSpeed);
        public abstract int Turn();
    }

    class Plane:Vehicle
    {
        public double Height { get; set; }
        public Plane(string id, string name, double miles, double height)
            : base(id, name, miles)
        {
            this.Height = height;
        }

        public override double Accelerate(double initSpeed)
        {
            return 5 * initSpeed;
        }

        public override int Turn()
        {
            return 20;
        }
    }

    class Car : Vehicle     
    { 
        public Car(string id, string name, double miles):base(id,name,miles){}

        public override double Accelerate(double initSpeed)
        {
            return 1.5 * initSpeed;
        }

        public override int Turn()
        {
            return 1;
        }
    }

    class Skoda : Car
    {
        public Skoda(string id, string name, double miles):base(id,name,miles){}

        public override double Accelerate(double initSpeed)
        {
            return 2 * initSpeed;
        }
    }

    
    class Program
    {
        static void Main(string[] args)
        {

            Vehicle[] vehicles = 
            {
                new Plane("pp01","big plane", 23000, 12000),
                new Car("cc02","small car", 12000),
                new Skoda("ss03","skoda",2300)
            };


            for (int i = 0; i < vehicles.Length; i++)
            {
                Console.WriteLine("id:{0}\t name:{1}\t miles:{2}\t speed:{3}\t time:{4}",vehicles[i].Id, vehicles[i].Name, vehicles[i].Miles, vehicles[i].Accelerate(100), vehicles[i].Turn());
            }
            Console.ReadLine();
        }
    }
}


2、在實驗1中的Car類定義一個方法或欄位,通過子類Skoda來實現隱藏,再將方法改為虛方法,子類中實現重寫,並在main方法中測試,理解方法的隱藏和重寫的區別。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ConsoleApplication2
{
    abstract class  Vehicle  
    {
        public string Id { get; set; }
        public string Name { get; set; }
        public double Miles { get; set; }

        public Vehicle(string id, string name, double miles)
        {
            this.Id = id;
            this.Name = name;
            this.Miles = miles;
        }

        public abstract double Accelerate(double initSpeed);
        public abstract int Turn();
    }

    class Plane:Vehicle
    {
        public double Height { get; set; }

        public Plane(string id, string name, double miles, double height)
            : base(id, name, miles)
        {
            this.Height = height;
        }

        public override double Accelerate(double initSpeed)
        {
            return 5 * initSpeed;
        }
        public override int Turn()
        {
            return 20;
        }
    }

    class Car : Vehicle
    {
        public Car(string id, string name, double miles)
            : base(id, name, miles)
        {            
        }

        public override double Accelerate(double initSpeed)
        {
            return 1.5 * initSpeed;
        }
        public override int Turn()
        {
            return 1;
        }

        public virtual void disp()
        {
            Console.WriteLine("method in car!");
        }

    }

    class Skoda : Car
    {
        public Skoda(string id, string name, double miles) : base(id, name, miles) { }
        public override double Accelerate(double initSpeed)
        {
            return initSpeed*2;
        }

        public new void disp()
        {
            Console.WriteLine("method in skoda!");
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            int[] arr = new int[5];
            Vehicle[] vehicles = new Vehicle[]
            {
                new Plane("pp01","plane",23000,18000),
                new Car("cc02","audi",10000),
                new Skoda("ss03","skoda",20000)
            };

            for (int i = 0; i < vehicles.Length; i++)
                Console.WriteLine("id:{0}\t name:{1}\tmiles:{2}\tspeed:{3}\t time:{4}",vehicles[i].Id, vehicles[i].Name,vehicles[i].Miles,vehicles[i].Accelerate(100),vehicles[i].Turn());

            Console.WriteLine("================");
            Skoda sk = new Skoda("ss02", "audi", 10000);
            Car newCar = sk;
            newCar.disp();  
            //如果前面的關鍵字是new,則是隱藏,顯示的是car中的方法
            //如果前面的關鍵字是override,則是重寫,顯示的是skoda中的方法

            Console.ReadLine();
        }
    }
}

對重寫和隱藏進行總結,如下:

    1、方法重寫:就是在基類中的方法用virtual關鍵字來標識,然後在繼承類中對該類進行重寫(override),這樣基類中的方法已經被重寫了,已經失去了功能了。當讓基類的物件的引用直接指向繼承類的物件時(多型性),呼叫該方法則是呼叫的繼承類的方法。

    2、方法隱藏:無論基類中的方法是否用了virtual關鍵字,繼承類中都可以用new關鍵字(如果不用new的話,不會產生錯誤,但會生成一個編譯警告)將基類中的方法隱藏,所謂隱藏就是隱藏,不像重寫,重寫就是原來的(基類中)已經不存在了,而隱藏是原來的還存在。所以當讓基類的物件的引用直接指向繼承類的物件時(多型性),呼叫該方法則是呼叫的基類的方法。


3、將實驗1上例中車輛類陣列中的元素按照已行駛的路程升序排序,並輸出排序後的陣列元素。

(略)

相關文章