Каково различие между наследованием и Категориями в Objective C

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

Ответ состоит из двух вещей:

1) Подготовка данных: я не знаю Ваш набор данных, но я буду угадывать

2) Отображение данных

<час>

1) а) Подготовка данных

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

Вы создаете сетку 11x11 в numpy (потому что от 0 до 10 - это 11 ячеек)

# chararray because you can initialize
# grid with being empty (empty string fields)
grid=np.chararray(shape=[11,11]) 

for part in part_list:
    grid[part.width,part.length] = str(part.part_number)
    #If you have 2 parts with same parameter you can sum up string so its flexible

Таким образом, в основном вы можете использовать индексы массива в качестве фактических параметров width и long [1112 ]

1) б) Подготовка данных

Ваша проблема каким-то образом запала мне в голову, пока я не нашел общее решение вашей проблемы (хотя я до сих пор не знаю ваш набор данных). На основе приведенного выше примера , если ваши параметры в любой форме (int, float, string), вы можете сделать это

# Lets say you have 3 types of widths and lengths and you index them 
# Key is your parameter, value is index position in grid
widths = {'7.2mm':0,'9.6mm':1,'11.4mm':2}
lengths = {'2.2mm':0,'4.8mm':1,'16.8mm':2}

header = [h for h in widths] # useless in this example
side = [s for s in lengths ] # but can serve for Data display part


grid=np.chararray(shape=[3,3])

for part in part_list:
    index_width = widths[part.width]
    index_lentgh = lengths[part.length]
    grid[index_width ,index_lentgh] = str(part.part_number)

# This way, you dont need to care about missing part numbers and grid can stay unfilled

2) Отображение данных [1115 ]

from prettytable import PrettyTable

def table(header,side,data):
    t = PrettyTable(['']+header)
    for i in range(len(data)):
        t.add_row([side[i]]+list(data[i]))
    print(t)

header = ['col1','col2','col3']
side =   ['row1','row2','row3']
data =   np.zeros(shape=[3,3])
>> table(header,side,data)

+------+------+------+------+
|      | col1 | col2 | col3 |
+------+------+------+------+
| row1 | 0.0  | 0.0  | 0.0  |
| row2 | 0.0  | 0.0  | 0.0  |
| row3 | 0.0  | 0.0  | 0.0  |
+------+------+------+------+

Вы можете кормить его чем угодно (например, классами)

data2 = [['','',PrettyTable],['World','',5],['','Hello','']]
table(header,side,data)
>>> table(header,side,data2)
+------+-------+-------+-----------------------------------+
|      |  col1 |  col2 |                col3               |
+------+-------+-------+-----------------------------------+
| row1 |       |       | <class 'prettytable.PrettyTable'> |
| row2 | World |       |                 5                 |
| row3 |       | Hello |                                   |
+------+-------+-------+-----------------------------------+

РЕДАКТИРОВАТЬ: Основываясь на данных выборки, я смог сделать то, что требовалось:

import numpy as np
widths = {'#10-24':0, '#10-32':1, '1/4-20':2, '5/16-18':3, '3/8-16':4, '1/2-13':5, '5/8-11':6, '3/4-10':7} # My data dictionary looks like
lenghts = {'5/8':0,'3/4':1,'7/8':2}
part_list = [{'part_number': 'FTC19-62', 'width': '#10-24', 'length': '5/8'},
        {'part_number': 'FTC19-75', 'width': '#10-32', 'length': '3/4'},
        {'part_number': 'FTC19-87', 'width': '#10-24', 'length': '7/8'}]

grid=np.chararray(shape=[len(lenghts),len(widths)]).astype('|S8')
grid[:,:] = ''

for part in part_list:
    index_width = widths[part['width']]
    index_lentgh = lenghts[part['length']]
    grid[index_lentgh,index_width] = str(part['part_number'])

header = sorted(widths, key=lambda k: widths[k])
side = sorted(lenghts, key=lambda k: lenghts[k])
from prettytable import PrettyTable

def table(header,side,data):
    t = PrettyTable(['']+header)
    for i in range(len(data)):
        t.add_row([side[i]]+list(data[i]))
print(t)


table(header,side,grid)


+-----+----------+----------+--------+---------+--------+--------+--------+--------+
|     |  #10-24  |  #10-32  | 1/4-20 | 5/16-18 | 3/8-16 | 1/2-13 | 5/8-11 | 3/4-10 |
+-----+----------+----------+--------+---------+--------+--------+--------+--------+
| 5/8 | FTC19-62 |          |        |         |        |        |        |        |
| 3/4 |          | FTC19-75 |        |         |        |        |        |        |
| 7/8 | FTC19-87 |          |        |         |        |        |        |        |
+-----+----------+----------+--------+---------+--------+--------+--------+--------+
>>> 
57
задан nevan king 3 February 2014 в 13:11
поделиться

4 ответа

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

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

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

Категории являются хорошим способом добавить функциональность, одновременно соответствуя объектно-ориентированному принципу для предпочтения состава по наследованию.

январь 2012 Редактирования

Вещи изменились теперь. С текущим компилятором LLVM и современным, 64-разрядным временем выполнения, можно добавить iVars и свойства к расширениям класса (не категории). Это позволяет Вам не допустить частный iVars в открытый интерфейс. Но, если Вы объявляете свойства для iVars, к ним можно все еще получить доступ / измененный через KVC, потому что нет все еще никакой такой вещи как закрытый метод в Objective C.

96
ответ дан Jack Humphries 24 November 2019 в 19:26
поделиться

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

, Чтобы видеть, насколько полезный это может быть, посмотрите на: CocoaDev

17
ответ дан Terry Wilcox 24 November 2019 в 19:26
поделиться

Категория похожа на смешивание: модуль в Ruby, или несколько как интерфейс в Java. Можно думать о нем как о "явных методах". Когда Вы добавляете Категорию, Вы добавляете методы к классу. Статья Wikipedia имеет хороший материал .

2
ответ дан mahboudz 24 November 2019 в 19:26
поделиться

Одна из любимых иллюстраций категорий Objective-c в действии - это NSString. NSString определен в структуре Foundation, которая не имеет представления о представлениях или окнах. Однако, если вы используете NSString в приложении Какао, вы заметите, что он отвечает на сообщения типа - drawInRect: withAttributes: .

AppKit определяет категорию для NSString, которая предоставляет дополнительные методы рисования. Категория позволяет добавлять новые методы в существующий класс, поэтому мы re все еще имеет дело с NSStrings. Если бы AppKit вместо этого реализовал рисование путем создания подклассов, нам пришлось бы иметь дело с «AppKitStrings» или «NSSDrawableStrings» или чем-то в этом роде.

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

11
ответ дан 24 November 2019 в 19:26
поделиться