26 oop polymorphism
我是OOP的新手.虽然我理解多态性是什么,但我无法真正使用它.我可以使用不同名称的函数.我为什么要尝试在我的应用程序中实现多态性.
Mar*_*ski 22
经典答案:想象一下基类Shape.它暴露了一种GetArea方法.想象一个Square类,一个Rectangle类和一个Circle类.而不是创建独立的GetSquareArea,GetRectangleArea和GetCircleArea方法,你能实现在每个派生类中只有一个方法.您不必知道Shape您使用的是哪个确切的子类,只需调用GetArea并获得结果,而不管它是哪种具体类型.
看看这段代码:
#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;
}
Run Code Online (Sandbox Code Playgroud)
这里要注意的一件重要事情是 - 您不必知道您正在使用的类的确切类型,只需要知道基类型,您将获得正确的结果.这在更复杂的系统中也非常有用.
玩得开心学习!
在严格类型化的语言中,多态性对于拥有不同类型的对象的列表/集合/数组很重要.这是因为列表/数组本身的类型只包含正确类型的对象.
想象一下,例如我们有以下内容:
// 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.
Run Code Online (Sandbox Code Playgroud)
要解决这个问题:
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
Run Code Online (Sandbox Code Playgroud)
它还使得处理项目列表更加简单.比如说所有的杂货都实现了这个方法price(),处理起来很简单:
int total = 0;
foreach (item in shoppingList) {
total += item.price();
}
Run Code Online (Sandbox Code Playgroud)
这两个特性是多态性的核心.
多态性是面向对象编程的基础.这意味着一个对象可以作为另一个项目.那么对象如何成为其他对象,可以通过以下方式实现
其中一个主要优点是交换机实现.假设您正在编写需要与数据库通信的应用程序.而且您碰巧定义了一个类,它为您执行此数据库操作,并期望执行某些操作,如添加,删除,修改.您知道数据库可以通过多种方式实现,它可以与文件系统或RDBM服务器(如MySQL等)通信.因此,作为程序员,您将定义一个可以使用的接口,例如......
public interface DBOperation {
public void addEmployee(Employee newEmployee);
public void modifyEmployee(int id, Employee newInfo);
public void deleteEmployee(int id);
}
Run Code Online (Sandbox Code Playgroud)
现在您可能有多个实现,假设我们有一个用于RDBMS,另一个用于直接文件系统
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
}
}
Run Code Online (Sandbox Code Playgroud)
让我们有文件系统数据库实现
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
}
}
Run Code Online (Sandbox Code Playgroud)
让我们看看主要如何在两者之间切换
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
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在许多地方使用多态概念,一个例子就是:让您编写图像decorer,并且您需要支持整组图像,如jpg,tif,png等.因此您的应用程序将定义一个接口和工作在它直接.并且您将为jpg,tif,pgn等每个实现各种实现的运行时绑定.
另一个重要的用途是,如果您使用的是Java,那么大部分时间您都可以使用List接口,这样您就可以在应用程序增长或需求发生变化时立即使用ArrayList或其他界面.
多态性的优点是客户端代码不需要关心方法的实际实现.请看下面的例子.在这里,CarBuilder对ProduceCar()一无所知.一旦给出汽车列表(CarsToProduceList),它将相应地生成所有必需的汽车.
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();
}
}
Run Code Online (Sandbox Code Playgroud)