Подтвердить что ты не робот

Каково реальное значение (использование) полиморфизма

Я новичок в ООП. Хотя я понимаю, что такое полиморфизм, но я не могу его реально использовать. Я могу иметь функции с другим именем. Почему я должен пытаться реализовать полиморфизм в своем приложении.

4b9b3361

Ответ 1

Классический ответ: представьте базовый класс 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;
}

Важно отметить, что вам не нужно знать точный тип используемого вами класса, просто базовый тип, и вы получите правильный результат. Это также очень полезно в более сложных системах.

Получайте удовольствие от обучения!

Ответ 2

Вы когда-нибудь добавляли два целых числа с +, а затем добавили целое число в число с плавающей запятой с помощью +?

Вы когда-нибудь регистрировались x.toString(), чтобы помочь вам отладить что-то?

Я думаю, вы, вероятно, уже оцениваете полиморфизм, просто не зная названия.

Ответ 3

В строго типизированном языке полиморфизм важен для того, чтобы иметь список/набор/массив объектов разных типов. Это потому, что сами списки/массивы печатаются, чтобы содержать только объекты правильного типа.

Предположим, например, что мы имеем следующее:

// 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();
}

Эти две функции являются ядром того, что делает полиморфизм.

Ответ 4

Преимущество полиморфизма - это клиентский код, который не нуждается в заботе о фактической реализации метода. Взгляните на следующий пример. Здесь 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();
    }
}

Ответ 5

Полиморфизм является основой объектно-ориентированного программирования. Это означает, что один объект может иметь как другой проект. Итак, как на объекте может стать другим, его возможно с помощью следующих

  • Наследование
  • Переопределение/реализация родительского поведения класса
  • привязка объекта времени выполнения

Одним из основных преимуществ этого является реализация коммутатора. Допустим, вы кодируете приложение, которое нужно поговорить с базой данных. И вы определяете класс, который выполняет эту операцию с базой данных для вас и ее ожиданий для выполнения определенных операций, таких как "Добавить", "Удалить", "Изменить". Вы знаете, что база данных может быть реализована по-разному, она может разговаривать с файловой системой или сервером 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 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, большую часть времени вы будете работать на интерфейсе List, чтобы вы могли использовать ArrayList сегодня или какой-либо другой интерфейс по мере роста вашего приложения или изменения его потребностей.

Ответ 6

Полиморфизм позволяет вам писать код, который использует объекты. Затем вы можете создавать новые классы, которые ваш существующий код может использовать без изменений.

Например, предположим, что у вас есть функция Lib2Groc(vehicle), которая направляет транспортное средство из библиотеки в продуктовый магазин. Он должен сказать, чтобы транспортные средства повернули налево, поэтому он может называть TurnLeft() на транспортном средстве между прочим. Затем, если кто-то позже изобретает новый автомобиль, например, на воздушной подушке, его можно использовать Lib2Groc без изменений.

Ответ 7

Вам не нужен полиморфизм.

Пока вы это сделаете.

Тогда его friggen awesome.

Простой ответ, который вы будете иметь дело много раз:

Кому-то нужно пройти через коллекцию вещей. Скажем, они просят коллекцию типа MySpecializedCollectionOfAwesome. Но вы имеете дело со своими примерами Awesome as List. Итак, теперь вам нужно создать экземпляр MSCOA и заполнить его каждым экземпляром Awesome, который у вас есть в вашем списке <T> . Большая боль в прикладе, правильно?

Хорошо, если бы они попросили IEnumerable <Awesome> , вы могли бы передать им одну из немногих коллекций Awesome. Вы можете передать им массив (Awesome []) или List (List <Awesome> ) или наблюдаемую коллекцию Awesome или ANYTHING ELSE, в которой вы держите свой Awesome в том, что реализует IEnumerable <T> .

Сила полиморфизма позволяет вам быть безопасным по типу, но достаточно гибким, чтобы вы могли использовать экземпляр много разных способов, не создавая тонны кода, который специально обрабатывает этот тип или этот тип.

Ответ 8

Я предполагаю, что иногда объекты динамически вызываются. Вы не уверены, будет ли объект треугольником, квадратом и т.д. В классической форме poly. пример.

Итак, чтобы оставить все это, мы просто вызываем функцию производного класса и предполагаем, что будет вызван один из динамических классов.

Вам будет безразлично, будет ли его квадрат, треугольник или прямоугольник. Вы просто заботитесь об этом районе. Следовательно, метод getArea будет вызываться в зависимости от переданного динамического объекта.

Ответ 9

Одним из наиболее важных преимуществ, которые вы получаете от полиморфных операций, является способность расширяться. Вы можете использовать одни и те же операции и не изменять существующие интерфейсы и реализации только потому, что столкнулись с необходимостью для некоторых новых вещей.

Все, что мы хотим от полиморфизма - упрощает наше дизайнерское решение и делает наш дизайн более расширяемым и элегантным. Вы также должны обратить внимание на принцип открытого закрытия (http://en.wikipedia.org/wiki/Open/closed_principle) и для SOLID (http://en.wikipedia.org/wiki/Solid_%28Object_Oriented_Design%29), которые помогут вам понять ключевые принципы OO.

P.S. Я думаю, вы говорите о "динамическом полиморфизме" (http://en.wikipedia.org/wiki/Dynamic_polymorphism), потому что есть такая вещь, как "Статический полиморфизм" (http://en.wikipedia.org/wiki/Template_metaprogramming#Static_polymorphism).

Ответ 10

Приложения с вкладками

Хорошее приложение для меня - это универсальные кнопки (для всех вкладок) в вкладке-приложении - даже браузер, который мы используем, реализует полиморфизм, поскольку он не знает вкладку, которую мы используем во время компиляции (в пределах код другими словами). Он всегда определяется во время выполнения (прямо сейчас! Когда мы пользуемся браузером.)