2011-01-06 2 views
1

Найти много авторов взаимозаменяемо, используя термин Тип и класс. Некоторые учебники, охватывающие объектно-ориентированную модель, также охватывают термин «Интерфейс».Значение типов, класса, интерфейса?

Не могли бы вы объяснить это простым языком на основе объектно-ориентированного программирования в целом и C++/Java/объектно-ориентированной базы данных в частности.

ответ

3

A тип - это классификация части данных, сообщающая вам, каковы ее допустимые значения и допустимые операции. (Почти?) Все языки программирования имеют типы, хотя типизирующая дисциплина значительно варьируется от одного языка к другому.

класса является частным видом типа в ООП языках, который определяется с определенным синтаксисом самого языка (в отличие, скажем, так называемым «родные типов», как в Java int или float или подобный, который определяется собственно языком). Класс обычно определяется с точки зрения макета памяти и кодирования данных (так называемые переменные-члены) и функции, которые работают на них (так называемые функции-члены или методы).

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

Это очень, очень, очень краткий обзор, который является своего рода упрощенной «средней формой» подхода к ним нескольких языков. Он игнорирует несколько краевых случаев и такие вещи, как способность C++ делать вещи, которые являются частью между интерфейсом и классом. Он также игнорирует, какие классы находятся в функциональных языках, таких как Haskell, потому что повреждение вашего мозга дальше не является целью здесь.;)


отредактирован, чтобы добавить некоторые примеры

Вот некоторые ява как декларации, чтобы помочь цементировать концепции.

int myVariable1; 

Эта переменная — myVariable1 — является родным (или примитивной) типа, состоящий из 32-разрядного целого числа, закодированного в 2с-комплемента нотации. Он имеет известный диапазон (от примерно -2 млрд до +2 млрд.) И известный набор операций (умножение, добавление, деление, модуль, вычитание, различные преобразования и т. Д.), Доступные ему.

class MyClass 
{ 
    int myMemberVariable; 
    int myOtherMemberVariable; 
    int myMethod(int p) { myMemberVariable += p; myOtherMemberVariable = p; } 
} 
MyClass myVariable2 = new MyClass(); 

Здесь myVariable2 тип определяется классаMyClass. MyClass определяет макет памяти (который в этом случае состоит из двух 32-разрядных целых чисел со знаком в примечании 2s-дополнения), а также единственной операции myMethod(), которая добавляет свой аргумент к myMemberVariable и устанавливает myOtherMemberVariable этому аргументу.

interface MyInterface 
{ 
    int myInterfaceMethod(int p, int q); 
} 

Здесь MyInterface только объявляет набор операций (состоящих в этом случае единственной функцией myInterfaceMethod()) без каких-либо переменных-членов, и без какой-либо реализации. Он только сообщает вам, что любой класс, реализующий этот интерфейс, гарантированно имеет метод с этой конкретной сигнатурой имени + возвращаемое значение + аргументы. Чтобы использовать его, вы должны создать класс, который реализует интерфейс.

class MyOtherClass implements MyInterface 
{ 
    int myMember1; 
    int myMember2; 
    int myMember3; 
    int myInterfaceMethod(int p, int q) { myMember1 = p; myMember2 = q; myMember3 = p - q; } 
    int myNonInterfaceMethod() { return myMember1; } 
} 
MyOtherClass myVariable3 = new MyOtherClass(); 

Теперь myVariable3 определяется как типа с планировкой памяти, состоящей из трех подписаны 32-битных целых и две операции. Одна из этих операций - одна, она должна реализовать из-за целого implements MyInterface часть. Таким образом, все, что ожидает (абстрактного) типа MyInterface, может использовать тип (бетон) MyOtherClass, так как операция гарантирована. Другой метод — myNonInterfaceMethod()не не принадлежит к MyInterface, поэтому что-то, что ожидает только MyInterface, не может его использовать, потому что он не может знать, что он существует.


далееотредактирован, чтобы добавить некоторые реальные вещи по запросу

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

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

class BankAccount 
{ 
    String accountNumber; 
    float balance; /* DO NOT USE FLOATING POINT IN REAL FINANCIAL CODE! */ 
    int transaction_limit; 
    float transaction(float change) { 
    balance += change > transaction_limit ? transaction_limit : change; 
    return balance; 
    } 
} 

Теперь вы можете сделать переменную этого типа и знать, что он будет носить номер счета (который сам по себе является String тип), баланс (который сам по себе является float, но НЕ ИСПОЛЬЗУЙТЕ ПЛАВУЮ ТОЧКУ В РЕАЛЬНОМ МИРОВОМ ФИНАНСОВОМ КОДЕЛЕ!) и лимит транзакции (который сам по себе является int). Вы также знаете, что можете совершить транзакцию (творчески называется transaction), которая проверит изменение по лимиту транзакции и изменит баланс. (Настоящий класс для этого будет содержать много больше и будет содержать много предметов обфускационной защиты, которые я удалил для педагогических целей.)

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

interface Transactable 
{ 
    float transaction(float change); 
} 

class BankAccount implements Transactable 
{ 
    /* interior is identical */ 
} 

class ReceivablesAccount implements Transactable 
{ 
    float balance; 
    float transaction(float change) { balance += change; } 
} 

Теперь все, что знает о типах Transactable, которые могут использовать как ваши BankAccount экземпляры, так и ваши экземпляры ReceivablesAccount. Им не нужно знать, что банковские счета имеют лимиты транзакций, а счета дебиторской задолженности - нет. Им не нужно ничего знать о внутреннем представлении данных. Им не нужно знать особые случаи чего-либо. Они просто должны знать об одной функции по имени (transaction()) и все. (Если вы хотите более конкретное использование в реальном мире этого, посмотрите, как классы коллекции, не говоря уже о цикле «for in», используют интерфейс Iterable в Java.)

+0

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

+0

О боже. Вы ясно объяснили это. Вы очень хороший учитель. Благодарю. –

3

В языке O.O.P очень распространено использование терминов Type и Class взаимозаменяемо, особенно когда речь идет о некоторых языках, таких как java и/или C++.

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

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

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

См. Теорию позади Abstract Data Types для дальнейшего понимания.

0

Класс - это шаблон для объекта , определяемый пользователем тип данных, который содержит переменные, свойства и методы.

//defines a simple class describing all types of fruit 
public class Fruit { 
    //insert fields here... 

    Fruit(){//constructor method 
     //insert constructor code here... 
    } 

    //insert class methods here.... 
} 

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

//The initialisation might look something like this. 
Fruit myFruit = new Fruit(); 

Предыдущая строка кода сообщает компилятору о создании нового объекта типа Fruit.

Таким образом, термин «класс» определяет свойства объектов (его данные), где «тип» относится к тому типу объектов, на который мы смотрим, когда он был создан, будь то «Плод», «Автомобиль», или стол!

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

Надеюсь, это поможет.

1

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

Большинство языков знают только о простых, примитивных «типах» таких вещей, как целые числа, символы и байты. Мы могли бы полностью использовать эти примитивные типы для описания типов вещей на кухне.Например, вы можете построить массив массива символов, где каждый индекс в массиве представляет собой атрибут чего-то. Например, индекс 0 представляет собой «тип» вещи, которую вы пытаетесь описать. Но, конечно, этот метод будет очень сложным очень быстро.

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

На примере кухни у нас есть концепция типа «Питание», «Устройство» и «Мебель». Для того, чтобы использовать эти новые типы в программе, мы должны были бы создать определение класса для каждого из них:

public class Food {...} 
public class Appliance {...} 
public class Furniture {...} 

Интерфейс описывает, как мы можем взаимодействовать с чем-то. Например, мы хотим создать инвентарь вещей на нашей кухне. Мы хотим иметь возможность «Добавить» в наш инвентарь, «Удалить» вещи из нашего инвентаря и, возможно, «Итерать» над нашим инвентарем. Действия «Добавить», «Удалить» и «Итерация» применяются практически ко всему списку (не только к нашей инвентаризации). Для этой цели Java предоставляет интерфейс с именем "List". Создавая объект инвентаризации с очень популярным и общим списком «Интерфейс», мы получаем все действия для свободных и других программистов могут посмотреть на нашей программе и точно знать, как взаимодействовать с «Inventory» объектом:

... 
java.util.List inventory = new ArrayList(); 
... 
//later in our program, we can interact with inventory 
// with any of methods on the list interface (because ArrayList "implements" List) 
inventory.add(new Furniture("chair")); 
inventory.add(new Appliance("refrigerator")); 
inventory.add(new Food("ice cream")); 
... 

Итак, в приведенном выше примере инвентарь является переменным, который содержит экземпляр типа ArrayList. Поскольку определение класса ArrayList реализует интерфейс «Список», все экземпляры Type ArrayList должны подчиняться контракту, определенному в интерфейсе «Список». Другими словами, мы могли бы так же, как легко создать inventory как LinkedList (вместо ArrayList), как это:

java.util.List inventory = new LinkedList(); 

Помните думать о интерфейсе как договор, который предоставляет определенный набор действий, которые необходимо предварительно , Поскольку LinkedList и ArrayList реализуют интерфейс «Список», они оба обязаны выполнять все методы в интерфейсе «Список».

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

Другими словами, LinkedList реализует метод «добавить», немного отличающийся от ArrayList. Но это не имеет значения для какого-либо кода, который хочет использовать нашу переменную «inventory».

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

java.util.List inventory = new CrazyMoonList(); 

Все другой код, который использует запасы могут оставаться точно так же, потому что CrazyMoonList гарантированно обеспечить «добавить», «удалить», и т.д.

Надеюсь, это поможет прояснить концепции!

+0

Этот реальный пример явно дал мне правильные понятия. У меня есть один вопрос. 'java.util.List инвентарь;' что это на самом деле означает?Таким образом, интерфейс «вообще» подкрепляет некоторые предопределенные вещи? –

+0

Прохладный, рад, что это помогло. Я немного поработал над понятием «интерфейс». Мне потребовалось много времени, чтобы полностью понять концепцию интерфейсов, так что не потейте, если вы не получите 100%. На самом деле вы, вероятно, не «получите», пока не будете использовать его несколько сотен, раз ;-) – Upgradingdave

Смежные вопросы