简介
多态性是面向对象的三大特征之一,个人的多态性往往是指,同一个方法在不同的代码环境下表现出来的不同功能,典型的用法就是在抽象类和接口中的使用。多态性,就是多种形态的形式,通常分为两种,静态的和动态的多态性。在静态多态性中,就是指函数或者方法在编译期间就发生的多种形态展示,典型的就是方法重载或者运算符重载;在动态多态性中,就是指函数或者方法在运行期间发生的多种形态方式,通常就是我们常见的类继承中抽象方法挥着虚方法重写;或者可以从另外一种角度进行分类,根据多态发生的作用域,可以将分为单类内部的多态性体现和继承类和父类之间的多态性体现。
编译多态性
在编译期间就可以实现多态性,也成为静态多态性。在C#中典型的有两种方式实现:
函数重载
运算符重载
函数重载,通常用于在同一作用域对相同的函数有多个定义,多种实现。但是定义之间必须存在编译器可识别的差异,就是函数签名必须不同,通常有三个要求:方法名称必须一致、参数列表必须不同、返回值随意。下面举一个例子:
using System;
namespace TestForPolymorphism
{
class Test
{
static void Main(string[] args)
{
Book book1= new Book(){BookName = "钢铁是怎样炼成的",BookID = "1",BookValue =45 };
Student student1 = new Student(){StudentName = "小王",StudentID = "20181215001"}
Library library1 = new Library();
library1.LoadBook(book1);
library1.LoadBook("钢铁是怎样炼成的","1",45,"");
Console.ReadKey();
}
}
public class Library
{
public Library(){}
private List<Book> booklist;
public List<Book> Booklist{get;set;}
private List<Student> studentlist;
public List<Student> Studentlist{get;set;}
private List<BorrowRecord> borrowlist;
public List<BorrowRecord> Borrowlist{get;set;}
private List<ReturnRecord> returnlist;
public List<ReturnRecord> Returnlist{get;set;}
public void LoadBook(Book bookitem)
{
Console.WriteLine("通过方法1,{0}已经登记到图书馆了!",bookitem.BookName);
}
public void LoadBook(string bookName,string bookId,int bookValue,string bookAuthor)
{
//Book bookitem = new Book(){...}可以先根据传进来的图书参数创建一个新的图书实例;
Console.WriteLine("通过方法2,{0}已经登记到图书馆了!",bookName);
}
}
public class Book
{
public Book(){}
public Book (string bookName,string bookID,int bookValue):this()
{
this.bookName = bookName;
this.bookID = bookID;
this.bookValue = bookValue;
}
private string bookName;
public string BookName{get;set;}
private string bookAuthor;
public string BookAuthor{get;set;}
private int bookValue;
public string BookValue{get;set;}
private string bookID;
public string BookID{get;set;}
}
public class Student
{
public Student(){}
public Student(string studentName,string studentID):this()
{
this.studentName = studentName;
this.studentID = studentID;
}
private string studentName ;
public string StudentName {get;set;}
private string studentID ;
public string StudentID {get;set;}
}
}
在上面的例子中,定义了三种类,图书馆Library,学生Student,书籍Book,在测试类Test中,进行实例化,并且调用实例library1的两种登记书籍的方法;这两个方法就是函数重载的一种,同时可以发现,在学生类和书籍类的构造函数,也可以认为是一种函数重载的体现,在实际代码编写中,我们也可以使用一个方法使用多个默认参数的方法来实现和函数重载相同的效果。
运算符重载,也是相同的道理,本章省略,以后在其他章节详细介绍。
运行多态性
在这个部分,主要是介绍程序在运行期间同一名称的方法的不同实现。典型的有类和继承类之间的方法重写override(继承多态性),以及类和接口之间的方法实现(实现多态性 ),可以重写的方法一般典型的有abstract修饰的抽象方法和使用virtual修饰的虚方法,实现接口的类在其内部必须实现接口的所有成员,就单独的方法成员来说,感觉接口方法就像抽象类的抽象方法一样,在定义的时候不能有实现,但是在继承类中必须有实现。
举个例子:
比如动物这个抽象类,它有叫(),喂食()等方法,描述具体的一种动物类比如猫,狗等,都继承自动物这个抽象类,在个自定义中
具体的实现方法有不同。如下代码:
using system;
namespace TestForPolymorphism
{
class Test
{
static void Main(string[] args)
{
Dog dog1= new Dog();
Cat cat1 = new Cat();
cat1.叫();
dog1.叫();
cat1.喂食();
dog1.喂食(); //继承多态性
cat1.bear(); //实现多态性
dog1.bear();
Console.ReadKey();
}
}
public abstract class Animal
{
public virtual void 叫(){}
public abstract void 喂食();
}
interface Ibearable
{
void bear();
}
public class Dog:Ibearable,Animal
{
public Dog(){}
public override void 叫()
{ Console.WriteLine("汪") ; }
public void 喂食()
{
Console.WriteLine("喂的狗粮") ;
}
public void bear()
{ Console.WriteLine("生的狗仔") ;}
}
public class Cat:Ibearable,Animal
{
public Cat(){}
public override void 叫()
{ Console.WriteLine("喵") ; }
public void 喂食()
{
Console.WriteLine("喂的猫粮") ;
}
public void bear()
{ Console.WriteLine("生的猫仔") ;}
}
}