What is the real significance(use) of polymorphism
我是新手。虽然我知道什么是多态性,但我不能真正使用它。我可以有不同名称的函数。为什么我要尝试在我的应用程序中实现多态性。
经典答案:想象一个基类
请看一下此代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 | #include <iostream> using namespace std; class Shape { public: virtual float GetArea() = 0; }; class Rectangle : public Shape { public: Rectangle(float a) { this->a = a; } float GetArea() { return a * a; } private: float a; }; class Circle : public Shape { public: Circle(float r) { this->r = r; } float GetArea() { return 3.14f * r * r; } private: float r; }; int main() { Shape *a = new Circle(1.0f); Shape *b = new Rectangle(1.0f); cout << a->GetArea() << endl; cout << b->GetArea() << endl; } |
这里需要注意的一件重要的事情是-你不必知道你所使用的类的确切类型,只需要知道基本类型,你就能得到正确的结果。这在更复杂的系统中也非常有用。
学习愉快!
你有没有用
您是否登录过
我想你可能已经很欣赏多态性了,只是不知道它的名字。
在严格类型化语言中,多态性对于拥有不同类型的对象的列表/集合/数组非常重要。这是因为列表/数组本身的类型是只包含正确类型的对象。
例如,假设我们有以下内容:
1 2 3 4 5 6 7 8 9 10 11 | // the following is pseudocode M'kay: class apple; class banana; class kitchenKnife; apple foo; banana bar; kitchenKnife bat; apple *shoppingList = [foo, bar, bat]; // this is illegal because bar and bat is // not of type apple. |
解决这个问题:
1 2 3 4 5 6 7 8 9 10 | class groceries; class apple inherits groceries; class banana inherits groceries; class kitchenKnife inherits groceries; apple foo; banana bar; kitchenKnife bat; groceries *shoppingList = [foo, bar, bat]; // this is OK |
它还使处理项目列表更加简单。比如说所有的杂货都是执行
1 2 3 4 | int total = 0; foreach (item in shoppingList) { total += item.price(); } |
这两个特性是多态性的核心功能。
多态性的优点是客户端代码不需要关心方法的实际实现。看看下面的例子。在这里,Carbuilder对ProduceCar()一无所知。一旦它得到一个汽车列表(CarstoProduceList),它将相应地生产所有必要的汽车。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 | class CarBase { public virtual void ProduceCar() { Console.WriteLine("don't know how to produce"); } } class CarToyota : CarBase { public override void ProduceCar() { Console.WriteLine("Producing Toyota Car"); } } class CarBmw : CarBase { public override void ProduceCar() { Console.WriteLine("Producing Bmw Car"); } } class CarUnknown : CarBase { } class CarBuilder { public List<CarBase> CarsToProduceList { get; set; } public void ProduceCars() { if (null != CarsToProduceList) { foreach (CarBase car in CarsToProduceList) { car.ProduceCar();// doesn't know how to produce } } } } class Program { static void Main(string[] args) { CarBuilder carbuilder = new CarBuilder(); carbuilder.CarsToProduceList = new List<CarBase>() { new CarBmw(), new CarToyota(), new CarUnknown() }; carbuilder.ProduceCars(); } } |
多态性是面向对象编程的基础。这意味着一个对象可以作为另一个项目来拥有。那么,在对象上如何能够成为其他对象,它可以通过以下方式实现
它的一个主要优点是交换机实现。假设您正在对需要与数据库对话的应用程序进行编码。您碰巧定义了一个类,它为您执行这个数据库操作,并且它预期会执行一些操作,比如添加、删除、修改。您知道数据库可以通过多种方式实现,它可以与文件系统或RDBM服务器(如mysql等)进行通信。因此,作为程序员,您将定义一个可以使用的接口,例如…
1 2 3 4 5 | public interface DBOperation { public void addEmployee(Employee newEmployee); public void modifyEmployee(int id, Employee newInfo); public void deleteEmployee(int id); } |
现在您可能有多个实现,假设我们有一个用于RDBMS,另一个用于直接文件系统。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | public class DBOperation_RDBMS implements DBOperation // implements DBOperation above stating that you intend to implement all // methods in DBOperation public void addEmployee(Employee newEmployee) { // here I would get JDBC (Java's Interface to RDBMS) handle // add an entry into database table. } public void modifyEmployee(int id, Employee newInfo) { // here I use JDBC handle to modify employee, and id to index to employee } public void deleteEmployee(int id) { // here I would use JDBC handle to delete an entry } } |
让我们实现文件系统数据库
1 2 3 4 5 6 7 8 9 10 11 | public class DBOperation_FileSystem implements DBOperation public void addEmployee(Employee newEmployee) { // here I would Create a file and add a Employee record in to it } public void modifyEmployee(int id, Employee newInfo) { // here I would open file, search for record and change values } public void deleteEmployee(int id) { // here I search entry by id, and delete the record } } |
让我们看看主管道如何在两者之间切换。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | public class Main { public static void main(String[] args) throws Exception { Employee emp = new Employee(); ... set employee information DBOperation dboper = null; // declare your db operation object, not there is no instance // associated with it if(args[0].equals("use_rdbms")) { dboper = new DBOperation_RDBMS(); // here conditionally, i.e when first argument to program is // use_rdbms, we instantiate RDBM implementation and associate // with variable dboper, which delcared as DBOperation. // this is where runtime binding of polymorphism kicks in // JVM is allowing this assignment because DBOperation_RDBMS // has a"is a" relationship with DBOperation. } else if(args[0].equals("use_fs")) { dboper = new DBOperation_FileSystem(); // similarly here conditionally we assign a different instance. } else { throw new RuntimeException("Dont know which implemnation to use"); } dboper.addEmployee(emp); // now dboper is refering to one of the implementation // based on the if conditions above // by this point JVM knows dboper variable is associated with // 'a' implemenation, and it will call appropriate method } } |
你可以在很多地方使用多态性概念,一个实用的例子是:让你写图像装饰,你需要支持整批图像,如JPG,TIF,PNG等,所以你的应用程序将定义一个接口并直接处理它。对于JPG、TIF、PGN等中的每一个,您都有一些不同实现的运行时绑定。
另一个重要用途是,如果您使用Java,大多数时候您将在列表接口上工作,以便在应用程序增长或需求改变时,可以使用ARRAYList或其他接口。
多态操作最显著的好处之一是扩展能力。您可以使用相同的操作,而不更改现有的接口和实现,因为您面临着一些新事物的需求。
我们只需要多态性来简化我们的设计决策,使我们的设计更具可扩展性和优雅性。您还应该注意开放-关闭原则(http://en.wikipedia.org/wiki/open/closed-u原则)和Solid(http://en.wikipedia.org/wiki/solid-28面向对象的u设计%29),它们可以帮助您理解主要的OO原则。
P.S.我认为你说的是"动态多态性"(http://en.wikipedia.org/wiki/dynamic_多态性),因为有"静态多态性"(http://en.wikipedia.org/wiki/template_metaprogramming_static_多态性)之类的东西。
多态性允许您编写使用对象的代码。然后,您可以稍后创建新的类,您的现有代码可以在不进行修改的情况下使用这些类。
例如,假设您有一个函数
选项卡式应用程序
对我来说,一个好的应用程序是选项卡应用程序中的通用按钮(对于所有选项卡),即使我们使用的浏览器也在实现多态性,因为它不知道我们在编译时使用的选项卡(换句话说,在代码中)。它总是在运行时确定(现在!当我们使用浏览器时。)
我想有时候对象是动态调用的。你不确定物体是否是一个三角形,正方形等在一个经典的形状多边形。例子。
所以,为了把所有这些都抛在脑后,我们只调用派生类的函数,并假设将调用动态类中的一个。
你不会在意它是正方形、三角形还是矩形。你只关心这个地区。因此,将根据传递的动态对象调用GetArea方法。
你不需要多态性。
直到你这样做。
那么它的金块棒极了。
简单的答案,你会处理很多次:
有人需要检查一些东西。假设他们要求一个类型为myspecializedcollectionofawesome的集合。但你一直在处理你的"超人名单"实例。所以,现在,您必须创建一个mscoa实例,并用您列表中的所有优秀实例填充它。屁股疼得厉害,对吧?
好吧,如果他们要一个IEnumerable,你可以给他们一个集合的Awesome。你可以给他们一个数组(Awesome[])或者一个列表(List
多态性的强大功能使您能够确保类型安全,同时也足够灵活,您可以使用许多不同的方法来使用实例,而无需创建大量专门处理此类型或该类型的代码。