C# 面向對象——多態,
多態分三種:1.虛方法
2.抽象類
3.接口
1、虛方法
1、將父類的方法標記為虛方法 ,使用關鍵字 virtual,這個函數可以被子類重新寫一個遍。
如:

![]()
class Program
{
static void Main(string[] args)
{
Chinese cn1 = new Chinese("韓梅梅");
Chinese cn2 = new Chinese("李雷");
American a1 = new American("科比布萊恩特");
American a2 = new American("奧尼爾");
Person[] pers = { cn1, cn2, a1, a2, };
for (int i = 0; i < pers.Length; i++)
{
pers[i].SayHello();
}
Console.ReadKey();
}
}
/// <summary>
/// 父類——人類
/// </summary>
public class Person
{
private string _name;
public string Name
{
get { return _name; }
set { _name = value; }
}
public Person(string name)
{
this.Name = name;
}
public virtual void SayHello()
{
Console.WriteLine("我是人類");
}
}
/// <summary>
/// 子類——中國人
/// </summary>
public class Chinese : Person
{
public Chinese(string name)
: base(name)
{
}
public override void SayHello()
{
Console.WriteLine("我是中國人,我叫{0}", this.Name);
}
}
/// <summary>
/// 子類——美國人
/// </summary>
public class American : Person
{
public American(string name)
: base(name)
{
}
public override void SayHello()
{
Console.WriteLine("我叫{0},我是米國人", this.Name);
}
}
View Code
2、抽象類
當父類中的方法不知道如何去實現的時候,可以考慮將父類寫成抽象類,將方法寫成抽象方法。

![]()
class Program
{
static void Main(string[] args)
{
//狗狗會叫 貓咪會叫
Animal a = new Cat();//new Dog();
a.Bark();
Console.ReadKey();
}
}
/// <summary>
/// 父類——動物
/// </summary>
public abstract class Animal
{
public virtual void T()
{
Console.WriteLine("動物有聲明");
}
private int _age;
public int Age
{
get { return _age; }
set { _age = value; }
}
public Animal(int age)
{
this.Age = age;
}
public abstract void Bark();
public abstract string Name
{
get;
set;
}
public Animal()
{
}
}
/// <summary>
/// 子類——測試
/// </summary>
public abstract class Test : Animal
{
}
/// <summary>
///子類——狗
/// </summary>
public class Dog : Animal
{
public override void Bark()
{
Console.WriteLine("狗狗旺旺的叫");
}
public override string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
/// <summary>
/// 子類——貓
/// </summary>
public class Cat : Animal
{
public override void Bark()
{
Console.WriteLine("貓咪喵喵的叫");
}
public override string Name
{
get
{
throw new NotImplementedException();
}
set
{
throw new NotImplementedException();
}
}
}
View Code
抽象類特點:
1).抽象成員必須標記為abstract,並且不能有任何實現。
public abstract class Animal
{
public abstract void Bark();
}
2).抽象成員必須在抽象類中。
3).抽象類不能被實例化
4).子類繼承抽象類後,必須把父類中的所有抽象成員都重寫。
(除非子類也是一個抽象類,則可以不重寫)
5).抽象成員的訪問修飾符不能是private
6).在抽象類中可以包含實例成員。
並且抽象類的實例成員可以不被子類實現
7).抽象類是有構造函數的。雖然不能被實例化。
8)、如果父類的抽象方法中有參數,那麼。繼承這個抽象父類的子類在重寫父類的方法的時候必須傳入對應的參數。
如果抽象父類的抽象方法中有返回值,那麼子類在重寫這個抽象方法的時候 也必須要傳入返回值。
3.接口

![]()
class Program
{
static void Main(string[] args)
{
IFlyable fly = new Bird();//new Person();
fly.Fly();
Console.ReadKey();
}
}
public class Person:IFlyable
{
public void Fly()
{
Console.WriteLine("人類在飛");
}
}
public class Student
{
public void Fly()
{
Console.WriteLine("人類在飛");
}
}
public class Bird : IFlyable
{
public void Fly()
{
Console.WriteLine("鳥在飛");
}
}
public interface IFlyable
{
//不允許有訪問修飾符 默認為public
//方法、自動屬性
void Fly();
}
public interface M1
{
void Test1();
}
public interface M2
{
void Test2();
}
public interface M3
{
void Test3();
}
public interface SupperInterface : M1, M2, M3
{
}
public class Car : SupperInterface
{
public void Test1()
{
throw new NotImplementedException();
}
public void Test2()
{
throw new NotImplementedException();
}
public void Test3()
{
throw new NotImplementedException();
}
}
View Code
接口是一種規范。
只要一個類繼承了一個接口,這個類就必須實現這個接口中所有的成員
為了多態。
接口不能被實例化。
也就是說,接口不能new(不能創建對象)
接口中的成員不能加“訪問修飾符”,接口中的成員訪問修飾符為public,不能修改。
(默認為public)
接口中的成員不能有任何實現(“光說不做”,只是定義了一組未實現的成員)。
接口中只能有方法、屬性、索引器、事件,不能有“字段”和構造函數。
接口與接口之間可以繼承,並且可以多繼承。
接口並不能去繼承一個類,而類可以繼承接口 (接口只能繼承於接口,而類既可以繼承接口,也可以繼承類)
實現接口的子類必須實現該接口的全部成員。
一個類可以同時繼承一個類並實現多個接口,如果一個子類同時繼承了父類A,並實現了接口IA,那麼語法上A必須寫在IA的前面。
class MyClass:A,IA{},因為類是單繼承的。
顯示實現接口的目的:解決方法的重名問題
什麼時候顯示的去實現接口:
當繼承的借口中的方法和參數一摸一樣的時候,要是用顯示的實現接口
當一個抽象類實現接口的時候,需要子類去實現接口。
======
如果父類中的方法有默認的實現,並且父類需要被實例化,這時可以考慮將父類定義成一個普通類,用虛方法來實現多態。
如果父類中的方法沒有默認實現,父類也不需要被實例化,則可以將該類定義為抽象類。