Есть ли больше к интерфейсу, чем наличие корректных методов

Определите массив и список меток:

In [67]: arr = np.arange(1,10).reshape(3,3)
In [68]: y = [56,76,87]

соедините список меток с массивом:

In [69]: arr1 = np.column_stack((y,arr))

определите строку заголовка:

In [70]: header = 'null,' + ','.join([str(i) for i in y])
In [71]: header
Out[71]: 'null,56,76,87'

write с savetxt. Обратите внимание на использование заголовка, комментариев и параметров fmt. Поиграйте с ними, если необходимо:

In [72]: np.savetxt('test.txt', arr1,header=header, fmt='%d',delimiter=',',comments='')
In [73]: cat test.txt
null,56,76,87
56,1,2,3
76,4,5,6
87,7,8,9

savetxt записывает заголовок с символом комментария. Затем он перебирает строки (1-й dim) массива массива. Для каждой строки выполняется запись fmt%tuple(row), где fmt выводится из вашего параметра. Таким образом, по своей сути это стандартная запись Python файла отформатированных строк.

159
задан Raedwald 21 June 2016 в 07:13
поделиться

13 ответов

Интерфейсы являются способом сделать Ваш код более гибким. То, что Вы делаете, является этим:

Ibox myBox=new Rectangle();

Затем позже, если Вы решаете, Вы хотите использовать другой вид поля (возможно, существует другая библиотека с лучшим видом поля), Вы переключаете свой код на:

Ibox myBox=new OtherKindOfBox();

, После того как Вы привыкаете к нему, Вы найдете, что это - большой (на самом деле существенный) способ работать.

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

myBox.close()

(принимающий IBox имеет завершение () метод) даже при том, что фактический класс myBox изменяется, в зависимости от которого поля Вы в в повторении.

143
ответ дан morgancodes 23 November 2019 в 21:33
поделиться

Интерфейсы, где fetature, добавленный к Java для разрешения множественного наследования. Разработчики Java, хотя/понял это имеющее множественное наследование было "опасной" функцией, именно поэтому прибытие с идеей интерфейса.

множественное наследование опасно, потому что у Вас мог бы быть класс как следующее:


class Box{
    public int getSize(){
       return 0;
    }
    public int getArea(){
       return 1;
    }

}

class Triangle{
    public int getSize(){
       return 1;
    }
    public int getArea(){
       return 0;
    }

}

class FunckyFigure extends Box, Triable{
   // we do not implement the methods we will used the inherited ones
}

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


   FunckyFigure.GetArea(); 

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

1
ответ дан mandel 23 November 2019 в 21:33
поделиться

Если у Вас есть CardboardBox и HtmlBox (оба из которых реализуют IBox), можно передать их обоих любому методу, который принимает IBox. Даже при том, что они и очень отличаются и не абсолютно interchangable, методы, которые не заботятся об "открытом" или "изменяют размер", могут все еще использовать Ваши классы (возможно, потому что они заботятся о том, сколько пикселей необходимо для отображения чего-то на экране).

1
ответ дан Todd R 23 November 2019 в 21:33
поделиться

Цель интерфейсов абстракция , или разъединяющийся от реализации.

при представлении абстракции в программе Вы не заботитесь о возможных реализациях. Вы интересуетесь , что это может сделать а не , как , и Вы используете interface для выражения этого в Java.

2
ответ дан eljenso 23 November 2019 в 21:33
поделиться

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

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

public interface Saveable {
....

public interface Printable {
....

и т.д. (Схемы именования не всегда работают, например, я не уверен Boxable, является соответствующим здесь)

3
ответ дан Brian Agnew 23 November 2019 в 21:33
поделиться

Яркий пример того, как интерфейсы используются, находится в платформе Наборов. Если Вы пишете функцию, которая берет List, то не имеет значения, если пользователь передает в Vector или ArrayList или HashList или что бы то ни было. И можно передать это List любой функции, требующей Collection или Iterable интерфейс также.

Это делает функции как Collections.sort(List list) возможными, независимо от того, как эти List реализован.

3
ответ дан Kip 23 November 2019 в 21:33
поделиться

Это - причина, почему Шаблоны "фабрика" и другие creational шаблоны так популярны в Java. Вы корректны, который без них Java не обеспечивает из механизма поля для легкой абстракции инстанцирования. Однако, Вы получаете абстракцию везде, где Вы не делаете , создают объект в Вашем методе, который должен быть большей частью Вашего кода.

Как в стороне, я обычно поощряю людей не следовать за механизмом "IRealname" для именования интерфейсов. Это - вещь Windows/COM, которая помещает один фут в могилу Венгерской записи и действительно не необходима (Java уже со строгим контролем типов, и смысл наличия интерфейсов должен иметь их максимально в основном неотличимый от типов классов).

3
ответ дан Christopher Smith 23 November 2019 в 21:33
поделиться

Вы могли сделать

Ibox myBox = new Rectangle();

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

6
ответ дан shivtej 23 November 2019 в 21:33
поделиться

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

, Если Вы инстанцируете, с помощью и выпуская объект все в узком объеме (например, в одном вызове метода), Интерфейс ничего действительно не добавляет. Как Вы отмеченный, известен реальный класс.

то, Где Интерфейсы полезны, - когда объект должен быть создан одно место и возвращен вызывающей стороне, которая не может заботиться о деталях реализации. Давайте изменим Ваш пример IBox на Форму. Теперь у нас могут быть реализации Формы, такие как Прямоугольник, Круг, Треугольник, и т.д., реализации getArea () и getSize (), методы будут полностью отличаться для каждого реального класса.

Теперь можно использовать фабрику со множеством createShape (параметрические усилители) методы, которые возвратятся, соответствующая Форма в зависимости от параметрических усилителей передала в. Очевидно, фабрика будет знать о том, какая Форма создается, но вызывающая сторона не должна будет заботиться о том, является ли это кругом или квадратом, или и так далее.

Теперь, предположите наличие множества операций, которые необходимо выполнить на формах. Возможно, необходимо отсортировать их по области, установить их всех на новый размер и затем отобразить их в UI. Формы все создаются фабрикой и затем могут быть переданы Сортировщику, Классификатору и классам Дисплея очень легко. Если необходимо добавить шестиугольный класс некоторое время в будущем, Вы ничего не должны изменять кроме фабрики. Без Интерфейса, добавляя другую форму становится очень грязным процессом.

6
ответ дан Ickster 23 November 2019 в 21:33
поделиться

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


public void foo(List l) {
   ... do something
}

Теперь Ваша функция foo принимает ArrayList с, LinkedList с... не только один тип.

самая важная вещь в Java состоит в том, что можно реализовать несколько интерфейсов, но можно только расширить ОДИН класс! Образец:


class Test extends Foo implements Comparable, Serializable, Formattable {
...
}
возможно, но

class Test extends Foo, Bar, Buz {
...
}
не!

Ваш код выше мог также быть: IBox myBox = new Rectangle();. Важная вещь теперь, что myBox ТОЛЬКО содержит методы/поля от IBox а не (возможно существующий) другие методы от Rectangle.

9
ответ дан Johannes Weiss 23 November 2019 в 21:33
поделиться

Интерфейсы позволяют статически типизированным языкам поддерживать полиморфизм. Объектно-ориентированный пурист настоял бы, чтобы язык обеспечил наследование, инкапсуляцию, модульный принцип и полиморфизм, чтобы быть полнофункциональным Объектно-ориентированным языком. В с динамическим контролем типов - или введенная утка - языки (как Smalltalk) полиморфизм тривиален; однако, на статически типизированных языках (как Java или C#) полиморфизм совсем не тривиален (на самом деле, на поверхности это, кажется, противоречит понятию строгого контроля типов.)

Позволяют мне продемонстрировать:

В с динамическим контролем типов (или введенная утка) язык (как Smalltalk), все переменные являются ссылками на объекты (ничто меньше и ничто больше.) Так, в Smalltalk, я могу сделать это:

|anAnimal|    
anAnimal := Pig new.
anAnimal makeNoise.

anAnimal := Cow new.
anAnimal makeNoise.

, Что код:

  1. Объявляет локальную переменную, названную anAnimal (обратите внимание, что мы НЕ указываем ТИП переменной - все переменные являются ссылками на объект, не больше и не меньше.)
  2. Создает новый экземпляр класса под названием "Свинья"
  3. , Присваивает тот новый экземпляр Свиньи к переменной anAnimal.
  4. Отправляет сообщение makeNoise свинье.
  5. Повторения все это с помощью коровы, но присваивая его той же точной переменной как Свинья.

тот же код Java выглядел бы примерно так (создание предположения, что Утка и Корова являются подклассами Животного:

Animal anAnimal = new Pig();
duck.makeNoise();

anAnimal = new Cow();
cow.makeNoise();

Это - все хорошо и хороший, пока мы не представляем класс Овощ. Овощи имеют часть того же поведения как Животное, но не все. Например, и Животное и Овощ смогли расти, но ясно овощи не шумят, и животные не могут быть получены.

В Smalltalk, мы можем записать это:

|aFarmObject|
aFarmObject := Cow new.
aFarmObject grow.
aFarmObject makeNoise.

aFarmObject := Corn new.
aFarmObject grow.
aFarmObject harvest.

Это работает отлично в Smalltalk, потому что он вводится уткой (если он идет как утка и шарлатаны как утка - это - утка.) В этом случае, когда сообщение отправляется в объект, поиск выполняется в списке методов получателя, и если метод сопоставления найден, это называют. В противном случае некоторое исключение NoSuchMethodError выдается - но оно все сделано во времени выполнения.

, Но в Java, статически типизированном языке, какой тип мы можем присвоить нашей переменной? Зерно должно наследоваться Овощу, для поддержки растут, но не может наследоваться Животному, потому что это не шумит. Корова должна наследоваться Животному для поддержки makeNoise, но не может наследоваться Овощу, потому что это не должно реализовывать урожай. Похоже, что нам нужно множественное наследование - способность наследоваться больше чем одному классу. Но это оказывается довольно трудной функцией языка из-за всех пограничных случаев, которые открываются (что происходит когда больше чем одна параллельная реализация суперкласса тот же метод?, и т.д.)

Вдоль прибывших интерфейсов...

, Если мы делаем и Овощные классы Животных с каждой реализацией Growable, мы можем объявить, что наша Корова является Животным, и нашим Зерном является Овощ. Мы можем также объявить, что и Животным и Овощем является Growable. Это позволяет нам записать это для роста всего:

List<Growable> list = new ArrayList<Growable>();
list.add(new Cow());
list.add(new Corn());
list.add(new Pig());

for(Growable g : list) {
   g.grow();
}

И это позволяет нам сделать это, сделать крики животных:

List<Animal> list = new ArrayList<Animal>();
list.add(new Cow());
list.add(new Pig());
for(Animal a : list) {
  a.makeNoise();
}

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

|aFarmObject|
aFarmObject := Corn new.
aFarmObject makeNoise. // No compiler error - not checked until runtime.

Статически типизированные языки обеспечивают намного лучше "программирование согласно контракту", потому что они поймают два вида ошибки ниже во время компиляции:

// Compiler error: Corn cannot be cast to Animal.
Animal farmObject = new Corn();  
farmObject makeNoise();

-

// Compiler error: Animal doesn't have the harvest message.
Animal farmObject = new Cow();
farmObject.harvest(); 

Так.... для суммирования:

  1. Интерфейсная реализация позволяет Вам указывать, какие виды вещей объекты могут сделать (взаимодействие), и Наследование классов позволяет Вам указать, как вещи должны быть сделаны (реализация).

  2. Интерфейсы приносят нам многую из пользы "истинного" полиморфизма, не жертвуя проверкой типа компилятора.

33
ответ дан Jared 23 November 2019 в 21:33
поделиться

Цель интерфейсов полиморфизм , иначе замена типа . Например, учитывая следующий метод:

public void scale(IBox b, int i) {
   b.setSize(b.getSize() * i);
}

При вызове scale метод, можно обеспечить любое значение, которое имеет тип, который реализует эти IBox интерфейс. Другими словами, если Rectangle и Square обе реализации IBox, можно обеспечить или Rectangle или Square везде, где IBox ожидается.

46
ответ дан Apocalisp 23 November 2019 в 21:33
поделиться

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

основное назначение уже находится на имя: они определяют интерфейс , что любой вообще может реализовать для использования всего кода, который воздействует на тот интерфейс. Лучший пример java.util.Collections, который обеспечивает все виды полезных методов, которые воздействуют исключительно на интерфейсы, такой как sort() или reverse() для List. Точка здесь - то, что этот код может теперь использоваться, чтобы отсортировать или инвертировать любой класс, который реализует List интерфейсы - не всего ArrayList и LinkedList, но также и классы, которые Вы пишете сами, который может быть реализован способом люди, которые записали java.util.Collections никогда не предполагаемый.

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

Другое общее использование интерфейсов для Обратных вызовов. Например, java.swing.table. TableCellRenderer, который позволяет Вам влиять, как таблица Swing показывает данные в определенном столбце. Вы реализуете тот интерфейс, передаете экземпляр эти JTable, и в какой-то момент во время рендеринга таблицы, Ваш код назовут, чтобы сделать его материал.

120
ответ дан Michael Borgwardt 23 November 2019 в 21:33
поделиться
Другие вопросы по тегам:

Похожие вопросы: