Абстракция и моё понимание

207
06 февраля 2020, 06:10

Абстра́кция в объектно-ориентированном программировании — это использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе. Основная идея состоит в том, чтобы представить объект минимальным набором полей и методов и при этом с достаточной точностью для решаемой задачи.

И вот еще информация

Так работает абстракция из ООП: мы вынесли важные данные и методы в базовый класс, а их различия оставили в их классах.

Работал с абстрактным классом и интерфейсом, но не очень понимаю определение, особенно из википедии:

использование только тех характеристик объекта, которые с достаточной точностью представляют его в данной системе, что?))

Из вот этого:

Так работает абстракция из ООП: мы вынесли важные данные и методы в базовый класс, а их различия оставили в их классах.

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

Абстракция является основой объектно-ориентированного программирования и позволяет работать с объектами, не вдаваясь в особенности их реализации.

Можно пример, непонятно как позволяет работать с объектами, не вдаваясь в особенности их реализации, заранее благодарю.

Answer 1

Абстракции нужны для декомпозиции, то есть для уменьшения сложности.

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

У абстракций есть уровни и они наследуют друг друга.

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

Примеры можно найти на каждом углу, например номенклатура в биологии.

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

Когда мы говорим о виде, например Сat или Dog, нас интересуют свойства вида или то что его определяет(генотип) и косвенно фенотип, например. то как животное "говорит" - "Гав" или "Мяу" (специально взял пример из уже приведенных ответов). Но нас не интересуют на этом уровне признаки особи, например клички питомцев (тузик и мурзик), они находятся на другом уровне абстракции.

А когда нас интересует тип (хордовые, к которому относятся собаки и кошки) нас не интересуют видовые признаки собак и кошек и мы ничего про них не знаем на данном "уровне абстракции", а клички нас тем более не интересуют.

Answer 2

Тут можно прибегнуть к класическим примерам из книжек по Java. Допустим мы хотим иметь в программе описание (абстракцию) животного. Но не всего разнообразия свойств животного, а лишь достаточную абстракцию для нашей программы. Допустим, нам достаточно знать, что животное может "говорить". Теперь мы описываем нашу абстракцию

public abstract class Animal {
    public abstract String talk();
}

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

public class Dog extends Animal {
    @Override
    public String talk() {
        return "Гав!";
    }
}
public class Cat extends Animal {
    @Overide
    public String talk() {
        return "Мяу!";
    }
}

Мы можем наделить другими свойствами объекты Dog и Cat. И если мы работаем в программе именно с этими классами мы можем оперировать этими свойствами. В случае, если мы работаем с абстракцией Animal, мы лишь знаем про то, что животное может "говорить".

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

public class AnimalTalks {
    public void doTalks (List<Animal> allAnimals) {
       for (Animal animal : allAnimals) {
           animal.talk();
       }
    }
}

Как-то так.

Answer 3

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

Для примера рассмотрим два конкретных типа: массив и односвязный список. Элементы (для определённости — числа) в массиве расположены в оперативной памяти подряд. Такие операции, как получение элемента по индексу выполняются за константное время O(1), а такие, как вставка — занимают время, пропорциональное длине массива O(N).

Элементы списка размещаются в куче и требуют хранения не только непосредственно чисел, но и ссылок на следующий узел. Вставка в начало списка выполняется за константное время O(1), а получение элемента по индексу — за время O(N).

Для некоторых алгоритмов такие характеристики, как скорость извлечения числа по индексу, являются определяющими. Например, быстрая сортировка Хоара на массиве выполняется за время O(N×log N), в то время, как на односвязном списке тот же самый алгоритм будет давать O(N2×log N) из-за накладных расходов на извлечение произвольного элемента.

Для других алгоритмов скорость работы на разных структурах будет идентична. Например, если мы хотим посчитать сумму чисел в коллекции, то и для массива и для списка эта операция потребует времени O(N).

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

В случае массива и списка мы можем абстрагироваться от деталей реализации и использовать паттерн проектирования Итератор. Мы скажем, что и массив и список — представители абстрактного типа коллекция или составной объект (Iterable), который позволяет перебирать свои элементы.

Массив и список будут реализовывать метод коллекции подать сюда итератор, в Java он называется iterator. Сам итератор также является абстрактным типом, который имеет методы hasNext, next и remove.

В результате мы можем написать универсальный метод вычисления суммы элементов целочисленной коллекции:

int sum(Iterable<int> iterable)
{
    int result = 0;
    Iterator<int> iterator = iterable.iterator();
    while (iterator.hasNext())
        result += iterator.next();
    return result;
}

Этот пример ещё нельзя назвать идеальным, но он демонстрирует преимущества абстрактных типов данных.

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

READ ALSO
Как создать класс?

Как создать класс?

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

195
Как проверить метод?

Как проверить метод?

Если метод сook в конечном счёте правильно отрабатывает, то он должен что-то вывестиТак вот как в JUnit тесте проверить, что метод cook что добавил...

226
Ожидание результата EditText в цикле for

Ожидание результата EditText в цикле for

Есть ArrayList в котором находятся словаЕсть EditText куда пользователь вписывает это же слово

210
Как сохранить состояние кнопки в RecyclerView, после выхода из Activity?

Как сохранить состояние кнопки в RecyclerView, после выхода из Activity?

Вопрос заключается в следующем : У меня есть список RecyclerView, где возле каждого item есть кнопка(с картинкой)При нажатии на кнопку, изображение...

177