首页 > Python基础教程 >
-
C#教程之面向对象三大特性之多态
多态是什么?
用一句话来概括下,多态就是同一操作(方法)作用于不同的对象时,可以有不同的解释,产生不同的执行结果。这句话看似简
单,实则颇有深意。下面我们来深入理解一多态的意义及如何使用多态。
使用多态编程的好处
在使用继承编程的时候,我们一般是把不同子类的方法分别写在不同的子类中,使用的时候用is a关键字来判断对象是哪种类型
的,然后进行强制转换来使用不同对象的方法。
但是,如果有多个子类的话,使用的时候难道要写多个if语句来判断对象是哪种类型的吗?这样会产生很多冗余代码,也会很繁
琐。
使用多态编程可以很好的解决这个问题。在父类写一个虚方法或抽象方法,子类去重写父类的方法,在调用的时候系统会根据对
象运行时的类型决定调用哪个方法。这样子是不是简洁多了?
小例子
假设我们有一个“书”类,然后有很多子类继承“书”类。例如“计算机组成原理”类继承“书类”,“深入Java面向对象”继承“书”类...
而这些子类都有类似的方法,即被不同的人使用。
下面我们来用代码实现它。
1 /// <summary> 2 /// 演示类 3 /// </summary> 4 class Demo 5 { 6 List<Book> books = new List<Book>(); 7 8 /// <summary> 9 /// 测试 10 /// </summary> 11 public void Test() 12 { 13 books.Add(new ComputerBook()); 14 books.Add(new JavaBook()); 15 16 foreach (Book item in books) 17 { 18 if (item is ComputerBook) 19 { 20 ((ComputerBook)item).ByReading(); 21 } 22 if (item is JavaBook) 23 { 24 ((JavaBook)item).ByReading(); 25 } 26 } 27 } 28 } 29 30 /// <summary> 31 /// 书类 32 /// </summary> 33 class Book 34 { 35 36 } 37 38 /// <summary> 39 /// 计算机书籍 40 /// </summary> 41 class ComputerBook : Book 42 { 43 /// <summary> 44 /// 被阅读 45 /// </summary> 46 public void ByReading() 47 { 48 Console.WriteLine("我是计算机类书籍,被在校大学生使用。"); 49 } 50 } 51 52 /// <summary> 53 /// Java书籍 54 /// </summary> 55 class JavaBook : Book 56 { 57 /// <summary> 58 /// 被阅读 59 /// </summary> 60 public void ByReading() 61 { 62 Console.WriteLine("我是Java书籍,被在业Java程序员使用。"); 63 } 64 }
通过这段代码可以发现:在使用子类对象的时候需要先用is a来判断子类对象时哪种类型的。那么也就是说,如果一个父类有10
个派生类(子类)的话,就要用10个if判断语句来判断子类对象是哪种类型了,未免太过繁琐。
这时,虚方法就该登场了。
虚方法
概念:
虚方法有方法体,可以被重写,使用virtual来修饰。
父类中的虚方法并非必须被子类重写,在父类中可以给出虚方法的默认实现。如果子类不重写父类的虚方法则依然执行
父类的默认实现。如果子类重写了父类的虚方法,则执行子类重写后的方法。
其实方法重载也是实现多态的一种形式,只是重载的方法都在同一个类中,而用虚方法实现多态的方法散布在有继承关
系的多个类中。
使用:
在父类中使用virtual关键字定义虚方法,在子类中使用override关键字来重写父类中的虚方法。
override关键字:
通过override关键字来修饰的方法,称为方法的重写。
下面我们用虚方法来改造一下上面的例子
1 /// <summary> 2 /// 演示类 3 /// </summary> 4 class Demo 5 { 6 List<Book> books = new List<Book>(); 7 8 /// <summary> 9 /// 测试 10 /// </summary> 11 public void Test() 12 { 13 books.Add(new ComputerBook()); 14 books.Add(new JavaBook()); 15 //遍历时不用加判断 16 foreach (Book item in books) 17 { 18 item.ByReading(); 19 } 20 } 21 } 22 23 /// <summary> 24 /// 书类 25 /// </summary> 26 class Book 27 { 28 public virtual void ByReading() 29 { 30 31 } 32 } 33 34 /// <summary> 35 /// 计算机书籍 36 /// </summary> 37 class ComputerBook : Book 38 { 39 /// <summary> 40 /// 被阅读 41 /// </summary> 42 public override void ByReading() 43 { 44 Console.WriteLine("我是计算机类书籍,被在校大学生使用。"); 45 } 46 } 47 48 /// <summary> 49 /// Java书籍 50 /// </summary> 51 class JavaBook : Book 52 { 53 /// <summary> 54 /// 被阅读 55 /// </summary> 56 public override void ByReading() 57 { 58 Console.WriteLine("我是Java书籍,被在业Java程序员使用。"); 59 } 60 }
可以看出,使用虚方法来写代码简便了许多。但是问题又来了,一般子类的父类和在父类中的虚方法是“宏观”的,“抽象”的,我
们不想让这个父类被实例化并且只提供方法的定义,由子类去实现这个方法,该怎么做呢?
如何解决这个问题呢?我们可以使用抽象类和抽象方法来实现。
抽象类和抽象方法
abstract关键字:
abstract关键字用来修饰抽象类和抽象方法。
抽象类:
使用abstract关键字修饰的抽象类不能被实例化。
抽象类中可以有非抽象方法。
抽象类不能是密封的或者静态的。
抽象方法:
使用abstract关键字修饰的抽象方法是一个没有实现的方法,由子类重写抽象方法来实现。
抽象方法没有大括号,直接在小括号后以分号";"结尾。
含有抽象方法的类必须是抽象类。
抽象方法必须在其子类中实现,除非它的子类也是抽象类。
下面我们使用抽象类和抽象方法再次改造上面的例子
1 /// <summary> 2 /// 演示类 3 /// </summary> 4 class Demo 5 { 6 List<Book> books = new List<Book>(); 7 8 /// <summary> 9 /// 测试 10 /// </summary> 11 public void Test() 12 { 13 books.Add(new ComputerBook()); 14 books.Add(new JavaBook()); 15 //遍历时不用加判断 16 foreach (Book item in books) 17 { 18 item.ByReading(); 19 } 20 } 21 } 22 23 /// <summary> 24 /// 书类 25 /// </summary> 26 abstract class Book 27 { 28 public abstract void ByReading(); 29 } 30 31 /// <summary> 32 /// 计算机书籍 33 /// </summary> 34 class ComputerBook : Book 35 { 36 /// <summary> 37 /// 被阅读 38 /// </summary> 39 public override void ByReading() 40 { 41 Console.WriteLine("我是计算机类书籍,被在校大学生使用。"); 42 } 43 } 44 45 /// <summary> 46 /// Java书籍 47 /// </summary> 48 class JavaBook : Book 49 { 50 /// <summary> 51 /// 被阅读 52 /// </summary> 53 public override void ByReading() 54 { 55 Console.WriteLine("我是Java书籍,被在业Java程序员使用。"); 56 } 57 }
到了这里,我们可以发现使用虚方法和抽象方法来编程(也就是多态)更符合面向对象编程的思想,并且可以大幅的提升代码的
可读性和减少冗余的代码。
用更少的代码实现相同的实现,这感觉,很爽的。