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

Чтобы исключить исключительное исключение индекса массива, следует использовать инструкцию расширенный- for , где и когда они могут.

Основная мотивация (и использовать), когда вы выполняете итерацию, и вам не требуются сложные шаги итерации. Вы не могли бы использовать расширенный for для перемещения назад в массиве или только для итерации на каждом другом элементе.

Вы гарантированно не исчерпали элементы для повторения при этом, а ваш [исправленный] пример легко конвертируется.

Код ниже:

String[] name = {"tom", "dick", "harry"};
for(int i = 0; i< name.length; i++) {
    System.out.print(name[i] + "\n");
}

... эквивалентен этому:

String[] name = {"tom", "dick", "harry"};
for(String firstName : name) {
    System.out.println(firstName + "\n");
}

26
задан MatrixFrog 17 January 2010 в 07:29
поделиться

8 ответов

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

Представьте, например, у нас есть следующее:

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

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

8
ответ дан 28 November 2019 в 06:48
поделиться

Можно использовать немедленное окно Visual Studio. Это позволит оценить различные выражения.

-121--3339057-

Классический ответ: Представьте базовый класс Форма . Он предоставляет метод GetArea . Представьте себе класс Square и класс Rectangle и класс Circle . Вместо создания отдельных методов GetSquityArea , GetRectanageArea и 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;
}

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

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

-121--2098115-

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

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

1
ответ дан 28 November 2019 в 06:48
поделиться

В качестве предварительного комментария TDD принимает практику. Когда я оглядываюсь на тесты, которые я написал, когда начал TDD, я вижу много проблем, так же, как когда я смотрю на код, который я написал несколько лет назад. Продолжайте делать это, и точно так же, как вы начинаете распознавать хороший код от плохого, то же самое произойдет с вашими испытаниями - с терпением.

Как составить такой список? Я первоначально имел несколько предметы, таких как "server должен запускаться, сервер должен прерываться если канал недоступен "и т.д., но они смешались и, наконец, сейчас, это просто что-то вроде "клиент должен быть возможность подключения к серверу "

" Список "может быть довольно неформальным (это так в книге Бека), но когда вы переходите к превращению предметов в тесты, попробуйте написать утверждения в формате" [Когда что-то происходит с этим] тогда [это условие должно быть правдой на этом] ". Это заставит вас задуматься о том, что именно вы проверяете, как вы бы его верифицируете и переводите непосредственно в тесты - или если это не так, это должно дать вам представление о том, какая часть функциональности отсутствует. Мысленный вариант использования/сценарий. Например, «сервер должен запуститься» неясно, потому что никто не инициирует действия.

Каждый раз, когда все менялось, я находил, что Мне пришлось переписать значительные части тесты, которые раздражали. Я бы полагали, что тесты будут несколько неизменное руководство во время моего развитие. Они просто чувствовали себя больше код для обработки.

Во-первых, да, тесты являются более кодовыми и требуют технического обслуживания - и написание ремонтируемых тестов требует практики. Я согласен с С. Лоттом, если вам нужно много менять свои тесты, вы, вероятно, тестируете «слишком глубоко». В идеале требуется протестировать на уровне открытого интерфейса, который вряд ли изменится, а не на уровне деталей внедрения, которые могут развиваться. Но часть упражнения о том, чтобы придумать дизайн, так что вы должны ожидать, чтобы получить некоторые из этого неправильно и должны переместить/рефакторировать ваши тесты, а также.

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

Не совсем уверен в этом. Из его звучания использовать макет было правильной идеей: взять одну сторону, издеваться над другой, и проверить, что каждая сторона работает, предполагая, что другая реализована правильно. Тестирование всей системы вместе представляет собой интеграционное тестирование, которое также необходимо выполнить, но обычно не является частью процесса TDD.

«Подделать, пока ты не сделаешь это» оставил меня с большим количеством грязного кода, который я позже потратил много времени на рефакторинг и очистить. Это путь вещи работают?

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

Я думаю, что мог бы сделать это за день если бы я использовал модульные тесты после кодовый путь.Я не вижу выигрыша.

Опять же, это требует практики, и вы должны стать быстрее со временем. Также иногда TDD более плодотворен, чем другие, я нахожу, что в некоторых ситуациях, когда я точно знаю код, который я хочу написать, просто быстрее написать хорошую часть кода, а затем написать тесты.
Кроме Бека, мне понравилась книга Роя Ошерова «Искусство модульного тестирования». Это не книга TDD, и она ориентирована на .Net, но вы, возможно, захотите взглянуть на нее в любом случае: хорошая часть о том, как писать ремонтируемые тесты, тесты качества и связанные с этим вопросы. Я обнаружил, что книга нашла отклик в моем опыте после письменных тестов и иногда пытался сделать это правильно...
Так что мой совет: не бросай полотенце слишком быстро и дай ему время. Вы также можете дать ему шанс на что-то более простое - тестирование связи с сервером не похоже на самый простой проект для начала!

-121--1579641-

Можно использовать немедленное окно Visual Studio. Это позволит оценить различные выражения.

-121--3339057-

Классический ответ: Представьте базовый класс Форма . Он предоставляет метод GetArea . Представьте себе класс Square и класс Rectangle и класс Circle . Вместо создания отдельных методов GetSquityArea , GetRectanageArea и 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;
}

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

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

22
ответ дан 28 November 2019 в 06:48
поделиться

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

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

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

0
ответ дан 28 November 2019 в 06:48
поделиться

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

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

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

16
ответ дан 28 November 2019 в 06:48
поделиться

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

Все, что мы хотим от полиморфизма - упрощает наше проектное решение и сделать наш дизайн более расширяемыми и элегантными. Вы также должны привлечь внимание к открытому закрытому принципу ( http://en.wikipedia.org/wiki/Open/clued_principle ) и для твердого вещества ( 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).

1
ответ дан 28 November 2019 в 06:48
поделиться

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

  1. Наследование
  2. Определив / внедрение поведения родительского класса
  3. Привязка объекта выполнения

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

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
    }
}

позволяет увидеть, как основной может переключаться между двумя

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              
    }
}

, вы можете использовать концепцию полиморфизма в Многие места, один пример Praticle: позволяет писать декор изображения, и вам нужно поддерживать целую кучу изображений, таких как jpg, tif, png и т. Д., Итак, ваше приложение будет определять интерфейс и работать над ним напрямую. И у вас будет некоторое обязательное время выполнения различных реализаций для каждого из JPG, TIF, PGN и т. Д.

другое важное использование, если вы используете Java, в большинстве случаев вы будете работать над интерфейсом списка, чтобы вы могли Используйте ArrayList сегодня или какой-либо другой интерфейс, поскольку ваша заявка растет или его необходимо изменить.

5
ответ дан 28 November 2019 в 06:48
поделиться

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

пока вы не сделаете.

Тогда его фригген потрясающий.

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

Кто-то нужно пройти через коллекцию вещей. Допустим, они просят коллекции типа MyspecializedCollectorefawesome. Но вы имели дело с вашими случаями потрясающего как список. Итак, теперь вам придется создать экземпляр Mscoa и заполнить его каждый экземпляр удивительного у вас в вашем списке . Большая боль в приклад, верно?

Ну, если они попросили IEnumerable , вы могли бы передать им одну из многих коллекций потрясающих. Вы можете передать им массив (Awesome []) или список (список ) или наблюдаемую коллекцию потрясающего или что-то еще, что вы держите свой потрясающий в этом, что это реализует iEnumerable .

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

0
ответ дан 28 November 2019 в 06:48
поделиться