Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/oop/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Oop 多态性的真正意义(用途)是什么_Oop_Polymorphism - Fatal编程技术网

Oop 多态性的真正意义(用途)是什么

Oop 多态性的真正意义(用途)是什么,oop,polymorphism,Oop,Polymorphism,我是OOP新手。虽然我了解多态性是什么,但我不能真正使用它。我可以有不同名称的函数。为什么我要尝试在我的应用程序中实现多态性。经典答案:想象一个基类Shape。它公开了一个GetArea方法。想象一个正方形类和一个矩形类,以及一个圆形类。与创建单独的GetSquareArea、GetRectangleArea和GetCircleArea方法不同,您只需要在每个派生类中实现一个方法。您不必知道使用的是Shape的哪个确切子类,只需调用GetArea即可得到结果,与具体类型无关 请查看以下代码: #

我是OOP新手。虽然我了解多态性是什么,但我不能真正使用它。我可以有不同名称的函数。为什么我要尝试在我的应用程序中实现多态性。

经典答案:想象一个基类
Shape
。它公开了一个
GetArea
方法。想象一个
正方形
类和一个
矩形
类,以及一个
圆形
类。与创建单独的
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;
}
#包括
使用名称空间std;
阶级形态
{
公众:
虚拟浮点GetArea()=0;
};
类矩形:公共形状
{
公众:
矩形(浮动a){this->a=a;}
float GetArea(){返回a*a;}
私人:
浮动a;
};
班级圈子:公共形态
{
公众:
圆(浮动r){this->r=r;}
float GetArea(){return 3.14f*r*r;}
私人:
浮子r;
};
int main()
{
形状*a=新圆(1.0f);
形状*b=新矩形(1.0f);

cout GetArea()多态性允许您编写使用对象的代码。然后您可以创建新的类,您的现有代码无需修改即可使用这些类


例如,假设您有一个函数
Lib2Groc(vehicle)
,用于将车辆从图书馆引导到杂货店。它需要告诉车辆左转,以便调用
turnlight()
在车辆对象上。如果后来有人发明了一种新的车辆,比如气垫船,它可以被
Lib2Groc使用,无需修改。

您不需要多态性

除非你这么做

那就太可怕了

简单的回答,你会处理很多次:

有人需要浏览一系列资料。比如说,他们要求收集类型为MySpecializedCollectionofWesome的资料。但你一直在处理你的Awesome as列表实例。所以,现在,你必须创建一个MSCOA实例,并用你列表中的每一个Awesome实例填充它。真让人头疼,对吧?

如果他们要一个IEnumerable,你可以给他们一个数组(Awesome[])或者一个列表(List)或者一个可观察到的集合,或者任何你把你的Awesome保存在实现IEnumerable中的东西


多态性的强大功能使您能够实现类型安全,同时又足够灵活,您可以通过多种不同的方式使用实例,而无需创建大量专门处理此类型或该类型的代码。

在严格类型化的语言中,多态性对于拥有不同类型对象的列表/集合/数组非常重要s,因为列表/数组本身的类型仅包含正确类型的对象

例如,假设我们有以下情况:

// 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.
要解决这个问题:

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
此外,它还使项目列表的处理更加简单。例如,所有杂货店都实现了方法
price()
,处理起来很简单:

int total = 0;
foreach (item in shoppingList) {
    total += item.price();
}

这两个特征是多态性的核心。

多态性是面向对象程序设计的基础,它意味着一个对象可以作为另一个项目。
  • 继承权
  • 重写/实现父类行为
  • 运行时对象绑定
  • 它的一个主要优点是交换机实现。假设您正在编写一个需要与数据库通信的应用程序。您碰巧定义了一个类,该类为您执行此数据库操作,并希望它执行某些操作,例如添加、删除、修改。您知道数据库可以通过多种方式实现,它可以e与文件系统或RDBM服务器(如MySQL等)交谈。因此,作为程序员,您可以定义一个可以使用的接口,如

    public interface DBOperation {
        public void addEmployee(Employee newEmployee);
        public void modifyEmployee(int id, Employee newInfo);
        public void deleteEmployee(int id);
    }
    
    现在您可能有多个实现,假设我们有一个用于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
        }
    }
    
    让我们实现文件系统数据库

    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
        }
    }
    
    让我们看看main如何在两者之间切换

    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或其他接口。

    我猜有时会动态调用对象。您不确定对象在经典应用程序中是否是三角形、正方形等形状多边形。例如

    所以,为了抛开所有这些东西,我们只需调用派生类的函数,并假设将调用动态类的函数


    您不在乎它是正方形、三角形还是矩形。您只关心面积。因此,将根据传递的动态对象调用getArea方法。

    您是否曾经使用
    +
    添加两个整数,然后使用
    +
    将整数添加到浮点数

    您是否曾经登录
    x.toString()
    以帮助您调试某些东西


    我想你可能已经很欣赏多态性了,只是不知道它的名字。

    多态操作最重要的好处之一是扩展能力。 您可以使用相同的操作,而不更改现有接口和实现
    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();
        }
    }