Лично так называемые классы в программировании являются той же концепцией, что и классы в реальном мире, которые классифицируют объекты, но они заимствованы в программировании. Классы представляют вещи, которые имеют ряд общих черт и одни и те же операции или действия, которые являются абстрактными типами данных в программировании. Каждый конкретный человек (в реальном мире) и переменные экземпляра (для программирования) являются объектами.
Класс - это представление общих функций (атрибутов и операций) определенных объектов в реальном мире, а объект является экземпляром класса.
Атрибуты класса: является аббревиатурой статических атрибутов класса, что относится к различным данным, содержащимся в классе, таких как переменные или другие объекты класса;
Служба класса: называется функцией или методом члена.
¨
Форма определения класса в Java заключается в следующем:
[Modifier] Имя класса класса [Extends Parent Class] [реализует имя интерфейса] {Объявление метода класса класса класса класса}Давайте подробно поговорим о каждой части:
Перед ключевым словом класса модификаторы класса, как правило, разделены на три типа: Модификаторы доступа Публичный публичный класс, окончательный модификатор (Окончательный спецификатор класса) и абстрактный модификатор (Abstract Class Specifier)
Среди них модификатор разрешения может быть только публичным или по умолчанию (то есть пустоте, ничего, что указывает на то, что он определяется как дружелюбный), а публичный означает, что класс может использоваться и доступ к где -нибудь (до тех пор, пока программа может найти местоположение класса), будь то в одном и том же пакете или в разных пакетах. Обратите внимание, что это отличается от C ++. C ++ не имеет модификатора для ограничения прав доступа к классу, но имеет права доступа к отношениям наследования между классами. Кроме того, все они имеют права доступа к атрибутам и методам класса. Разрешение на доступ к по умолчанию (то есть, определяемое как дружелюбное) означает, что его можно ссылаться только и доступ к классам в том же пакете, но не может быть доступен и ссылается на классы в других пакетах, даже если они импортируются.
Он также будет упомянут позже: когда будет использоваться модификатор атрибута и метода класса, также выражается, что на него можно ссылаться только классы в том же пакете.
Множественное наследство не допускается в Java, которая отличается от C ++. Чтобы восполнить этот недостаток, Java представила концепцию интерфейса.
В определении вышеупомянутого класса корпус класса в основном содержит конкретное содержание класса, включая атрибуты класса и методы класса. Свойства класса могут быть простыми переменными или экземплярами определенных классов. Если это экземпляр класса, его можно определить следующим образом:
[MODIFIER] ИМЯ КЛАССА Имя объекта Имя = Имя нового класса (список параметров);
При объявлении объектов и сложных переменных вы не можете использовать создание во время объявлений, но можете быть созданы в будущих конструкторах.
Методы, определенные в классе, обычно играют две роли: одна из них - выполнять различные операции вокруг атрибутов класса; Другой - выполнить обмен данными, доставку сообщений и другие операции с другими классами или объектами.
Синтаксис для объявления методов в Java заключается в следующем:
[MODIFIER] ВЕРНАЯ ЗНАЧЕНИЯ ИМЯ МЕТОДА МЕТОД (СПИСОК ПАРАМЕТРЕЙ) Обращает имя исключения 1, Имя исключения 2,… {МЕТОД КОЛИЦА: Объявление локальной переменной; операционная последовательность;}Методы класса, также известные как функции -члены, используются для указания операций на атрибутах класса и реализации внутренних функций классов. Они также являются важным окном для занятий для взаимодействия с внешним миром.
Программисты Java фокусируются на создании пользовательских типов, называемых классами. Классы также называются программистыми типами. Каждый класс содержит данные и набор методов манипулирования данными. Часть данных в классе называется переменными экземпляра. Экземпляр пользовательского типа (то есть класс) называется объектом.
Объект - это экземпляр класса. Класс - это абстракция того же типа объекта и шаблон для создания объекта. Создание объекта в программе откроет пространство в памяти, включая свойства и методы объекта. Создайте объект с помощью оператора ключевого слова New.
Конструктор (можно сравнить с C ++, который почти такой же, как C ++)
Создайте свой собственный конструктор
• Имя конструктора и имя класса одинаковы. При построении объекта класса сотрудника этот конструктор запускается, и поле экземпляра присваивается начальное значение. В Java определение и инициализация объединены - оба являются необходимыми.
Например, при создании экземпляра класса сотрудников со следующим кодом,
newemployee («Джеймс Бонд», 100000 1950,1,1);
Характеристики конструктора:
(1) Конструктор и класс имеют одинаковое имя.
(2) Класс может иметь несколько конструкторов.
(3) Конструктор может иметь 0, 1 или более параметров.
(4) Конструктор не имеет возвратного значения.
(5) Конструктор всегда вызывается с новым оператором.
Роль конструктора
(1) Инициализация объекта
(2) Внедрить большую гибкость (назначение переменных или более сложные операции)
(3) Конструктор не может быть определен на Java
Конструктор не может быть определен в Java, и система автоматически генерирует конструктор по умолчанию для системы. Название этого конструктора совпадает с именем класса, оно не имеет формальных параметров и не выполняет никаких операций.
Обзор метода
Программа Java состоит из определений класса, а класс имеет две части: свойства и методы. Что такое класс описания атрибутов и что делает класс описания метода. У любого объекта есть независимая память для хранения своих свойств. Все объекты класса делятся методом, хранящимся в памяти.
Другими словами: методы являются основным компонентом класса. В классе роль программы отражена в методе.
Метод состоит в том, чтобы создать названную подпрограмму от Java. Основной метод и несколько подметодов. Основной метод вызывает другие методы, и другие методы также могут быть вызваны друг к другу, и один и тот же метод можно назвать в любое время одним или несколькими методами.
Определение другого метода в одном методе создаст синтаксисную ошибку.
(1) Лучше всего избегать локальных переменных переменных "Маски" переменные экземпляра. Это может быть сделано без использования идентификатора того же имени в классе; Параметры в методах вызовы используются для передачи числовых значений и ссылок, а методы также могут быть вызваны вложенными и рекурсивно.
(2) Если в корпусе метода указан тип возвращаемого значения, не содержащий ветвления, метод должен включать оператор возврата, чтобы убедиться, что существует возвратное значение в любом случае, а оператор возврата не может сопровождаться каким-либо выражением;
Основная структура программ Java заключается в следующем:
Представить библиотеку классов Java; Определите пользовательский класс 1 {определить несколько переменных или объектов класса 1: определить метод 1 класса 1; определить метод 2 класса 1; … Определить метод M1 класса 1; } определить пользовательский класс 2 {определить несколько переменных или объектов класса 2: определить метод 1 класса 2; определить метод 2 класса 2; … Определите метод M2 класса 2}Java представила концепцию «модификатора управления доступом», которая позволяет создателям библиотеки объявлять то, что может использоваться клиентскими программистами, и что нельзя использовать.
Этот уровень контроля доступа находится между диапазоном «максимального доступа» и «минимальным доступом», включая: public, «по умолчанию» (без ключевого слова), защищенным и частным. В следующем списке объясняется значение модификаторов управления доступом:
Персонаж контроля доступа
Для занятий:
Есть только один контроллер доступа для класса в Java: публичная, то есть публичная. Класс объявляется как публичный класс, что указывает на то, что к нему можно получить доступ и ссылаться на все другие классы. Доступ и ссылка здесь относится к тому, что класс будет видимым и пригодным для использования в целом. Другие части программы могут создавать объекты этого класса, доступа к переменным элемента, видимые внутри класса, и вызывать его видимые методы.
Класс виден другим частям программы в целом и не представляет, что все свойства и методы в классе также видны для других частей программы. Первое является лишь необходимым условием для последнего. Доступ ли доступ к свойствам и методам класса доступны во всех других классах, зависит от символов управления доступом этих свойств и методов.
Используется для свойств в классе:
Атрибуты в классе, модифицированные общественностью, называются публичными атрибутами. Если этот класс является общедоступным классом, к ним можно получить доступ ко всем другим классам.
Управление доступа по умолчанию
Используется для занятий
Если класс не имеет символов управления доступом, это означает, что он имеет характеристики управления доступом по умолчанию. Этот контроль доступа по умолчанию предусматривает, что к классу можно получить доступ только к классам в том же пакете, и не может использоваться классами в других пакетах. Эта функция доступа называется доступностью пакета. Объявив символы управления доступом в классе, вся структура программы может быть ясной и строгой, уменьшая возможные межклассные помехи и ошибки.
Используется для атрибутов класса
Если свойства и методы в классе не ограничены символами управления доступом, они также указывают на то, что они являются доступностью пакетов.
3 Частный персонаж контроля доступа
Атрибуты или методы, модифицированные частными, могут быть доступны и изменены только самим классом, и их не могут быть получены и ссылаются любым другим классом, включая подклассы класса.
1). Например, частные данные имеют три поля экземпляра, которые содержат данные, которые работают внутри экземпляра класса сотрудников.
Приватное название строки;
частная двойная зарплата;
частное свидание
Приватное ключевое слово используется для обеспечения того, чтобы эти поля экземпляра были доступны только самим классом сотрудника.
2). ПРИБОРУЕТ МЕТОД При внедрении класса мы делаем все поля данных частными, потому что публичные данные опасны. Какова ситуация с методом? Хотя большинство методов являются государственными, частные методы также часто используются. Эти методы могут быть разделены только тем же методом.
Короче говоря, частный метод может быть выбран в следующих случаях:
(1) Те методы, которые не связаны с пользователем класса.
(2) Те методы, которые нелегко поддерживать, если изменяется внедрение класса.
Защищенный символ управления доступом защищен
Измененные переменные участника могут ссылаться на три типа: сам класс, другие классы в том же пакете, что и подклассы класса в других пакетах. Основной целью использования защищенного модификатора является разрешение его подклассов в других пакетах для доступа к определенным свойствам родительского класса.
Защищенное ключевое слово знакомит нас с концепцией, называемой «наследование», которая основана на существующих классах и добавляет к нему новых участников, не влияя на существующие классы - мы называем этот существующий класс «базовый класс» или «базовый класс». Это также может изменить поведение существующих членов этого класса. Для наследства от существующего класса мы говорим, что наш новый класс «расширяет» существующий класс
Частный защитный персонаж контролируемый защитный доступ
Частные и защищенные используются в последовательности, чтобы сформировать полный символ управления доступом: символ управления доступа к частной защите. Переменные члена, измененные с помощью PrivateProtected, могут быть доступны и ссылаются на два класса, один из них - сам класс, а другой - все подклассы класса, независимо от того, находятся ли эти подклассы в том же пакете, что и в классе или в других пакетах.
По сравнению с защищенным, модификатор PrivatePotto, исключающий не-подклассы в одном и том же пакете из доступной масштаба, что делает переменные участника более запатентованными для классов с явными отношениями наследования, а не пакеты, которые свободно сгруппированы вместе.
Статический модификатор
Статический называется статическим модификатором, который изменяет свойства и методы в классе.
Использование статического ключевого слова может соответствовать двум требованиям:
(1) Одна ситуация заключается в том, что вы хотите использовать только область хранения для сохранения конкретных данных - независимо от того, сколько объектов вы хотите создать, вы даже не создаете объекты вообще; Атрибуты, модифицированные Static, называются статическими свойствами, и одной из наиболее важных особенностей этого типа атрибута является то, что они являются атрибутами класса, а не конкретными объектами любого класса. Другими словами, для любого конкретного объекта этого класса статическое свойство является общим хранилищем. Когда любой объект любого класса обращается к нему, он получает одинаковое числовое значение. Когда любой объект любого класса изменяет его, он также выполняет операции на одном и том же блоке памяти.
(2) Другая ситуация заключается в том, что нам нужен специальный метод, который не связан с каким -либо объектом этого класса. То есть, даже если объект не создан, необходим метод, который можно назвать непосредственно классом.
Важной целью статического является помочь нам назвать этот метод без необходимости создавать объект.
Статические константы
Статические переменные редки. Однако статические константы распространены. Например, статическая константа определяется в классе математики:
Математика открытого класса
{… Public static final double pi = 3.1.4159265358979323846;…} Статический метод заявляет, что метод является статичным, имеет как минимум три значения:
(1) При использовании этого метода имя класса следует использовать в качестве префикса, а не как конкретное имя объекта;
(2) Нестатические методы-это методы, принадлежащие объекту. Когда этот объект создается, метод объекта имеет свой собственный сегмент кода в памяти; В то время как статический метод принадлежит всему классу, а его сегмент кода в памяти будет выделен и загружен в соответствии с определением класса и не будет исключительно для любого объекта;
(3) Поскольку статический метод принадлежит всему классу, он не может манипулировать и обрабатывать переменные элемента, принадлежащие к определенному объекту, но могут обрабатывать только переменные члена, принадлежащие всему классу.
5 Основной метод
Основной метод не применяет операции ни к одному объекту. На самом деле, когда программа начинает выполнять, еще не существует объектов. Статический метод выполняется, и построены объекты, требуемые программой.
Это подсказывает, что каждый класс может иметь основной метод. Это очень удобный трюк для классов модульных испытаний.
Аннотация - это абстрактный модификатор, который можно использовать для изменения классов или методов.
Аннотация класс
Когда класс объявляется абстрактным, этот класс называется абстрактным классом. Так называемый абстрактный класс-это класс без конкретных объектов экземпляра.
Чтобы решить эту проблему, Java предоставляет механизм, называемый «абстрактный метод». Он принадлежит к неполному методу, только с одним объявлением, и не имеет тела метода. Вот синтаксис, используемый при объявлении абстрактных методов:
Аннотация void x ();
Абстрактные методы
В качестве модификатора метода класса, абстрактный объявляет абстрактный метод, который имеет только заголовки метода, но нет конкретного тела метода и реализации операции.
Можно видеть, что абстрактный метод имеет только объявление заголовка метода, а полуколон используется для замены определения тела метода: что касается конкретной реализации тела метода, он завершается различными подклассами текущего класса в соответствующих определениях класса.
Следует отметить, что все абстрактные методы должны существовать в абстрактных классах
середина.
В дополнение к абстрактным методам, абстрактные классы также могут иметь конкретные данные и методы.
Абстрактные методы являются очень важными понятиями на языке программирования Java. Вы будете использовать его во многих отношениях в интерфейсе.
Примечание. Здесь нам нужно сравнить и запомнить с интерфейсом. Методы на границе раздела являются абстрактными методами. Конечно, в интерфейсе также есть атрибуты, и их конкретные свойства будут подробно описаны позже.
Окончательный класс, окончательный атрибут, окончательный метод и финализатор (нет окончательного модификатора в C ++)
Финал - это окончательный модификатор, который изменяет классы, свойства и методы. Кроме того, ключевые слова терминала очень похожи на финал и будут представлены вместе
Окончательный класс
Если класс объявлен окончательным, это означает, что он не может вывести новые подклассы и не может быть унаследован в качестве родительского класса. Следовательно, класс не может быть объявлен как абстрактным, так и окончательным.
Классы, определенные как конечные, обычно представляют собой некоторые классы со специальными функциями, которые используются для выполнения стандартных функций. Определение класса как окончательного может исправить свой контент, атрибуты и функции и сформировать стабильные отношения отображения со своим именем класса, что гарантирует, что функции, реализованные при ссылке на этот класс, являются точными.
Окончательные атрибуты
У многих языков программирования есть свои способы сказать компилятору, что определенные данные являются «постоянными». Константы в основном используются в следующих двух аспектах:
(1) Постоянная компиляция постоянная, он никогда не изменится;
(2) Мы не хотим, чтобы значение инициализировалось во время выполнения, чтобы измениться.
Поле экземпляра может быть определено как окончательное (не может быть изменено). Это поле должно быть инициализировано, когда объект построен. То есть необходимо обеспечить, чтобы значение было установлено до конца каждого конструктора. Значение поля не может быть изменено в будущем
Окончательный метод
Причина использования окончательного метода может быть связана с соображениями по двум причинам.
Во -первых, это «заблокировать» метод, предотвращающий изменение класса наследования, изменить свое первоначальное значение. При разработке программы эта практика может быть принята, если вы хотите, чтобы поведение метода оставалось неизменным во время наследования и не может быть перезаписана или переписана.
Вторая причина принятия окончательного метода - эффективность выполнения программы
Терминатор
Функция терминатора - это метод, выполненный при получении объектов. Аналогично методу, который конструкторы выполняются при создании объектов.
пример
Protected voidfinalize () {System.out.println (""); }Другие модификаторы
нестабильный
Если атрибут изменяется летучим, это означает, что этот атрибут можно контролировать и изменять несколько потоков одновременно.
синхронизированный
В основном используется для синхронизации потоков
родной
Это означает, что метод не написан на языке Java (он написан на C, C ++ и других языках)
Некоторая информация найдена в Интернете: - Внутренняя категория
Проще говоря, внутренние классы - это классы в классах, например:
Класс A {private int i; private void m () {} класс B {mm (int j) {i = j; m ();}}}Здесь B является внутренним классом A, который характеризуется удобным доступом к частным методам и свойствам во внешних классах. Например, здесь B может напрямую получить доступ к частным свойствам I и частным методам m () в A.
Наиболее важными особенностями объектно-ориентированного программирования являются инкапсуляция (также называемая абстракцией), наследование и полиморфизм. Как объектно-ориентированный язык программирования, Java имеет свои преимущества в этом отношении:
«Наследование-это форма повторного использования программного обеспечения, которая эффективна для снижения сложности программного обеспечения. Наследство также является особенностью объектно-ориентированного языка программирования. Языки, которые используют объекты, но не имеют наследства, являются объектно-ориентированными языками, но не объектно-ориентированными языками. Это различие между ними».
Взаимосвязь наследования между классами является прямым моделированием генетических отношений в реальном мире. Он представляет внутреннюю связь между классами и обменом атрибутами и операциями, то есть подклассы могут следовать определенным особенностям родительского класса (унаследованный класс). Конечно, подклассы также могут иметь свои собственные независимые свойства и операции
Наследование - это форма повторного использования программного обеспечения. Новые классы генерируются существующими классами, а новые атрибуты и поведение добавляются путем сохранения их свойств и поведения и изменения производительности в соответствии с требованиями нового класса. Если урок дочернего класса наследуется только от одного родительского класса, его называют единственным наследством; Если ребенок-класс наследует от более чем одного родительского класса, его называют многоуровневым. Обратите внимание, что Java не поддерживает множественное наследство, но поддерживает концепцию «интерфейса». Интерфейсы позволяют Java получить много преимуществ множественного наследства и отказаться от соответствующих недостатков. Примечание: C ++ поддерживает множественное наследование
Определение отношений наследования:
[Модификатор] Имя подкласса класса расширяет имя родительского класса, имя родителя 2
Имя родительского класса следует за расширение
Ключевое слово используется для указания, какой подкласс текущего класса уже есть, и существует отношения наследования.
Определите два подкласса сотрудника работника:
Общий категория работников: CommonMoployee
Категория супервайзера: Managermployee
Есть два основных аспекта наследования подкласса от родительского класса:
(1) Наследование атрибутов. Например, компания является родительским классом, а у компании есть имя, адрес, менеджер, сотрудник и т. Д., Которые являются структурными аспектами.
(2) Метод наследование. Родительский класс определяет несколько операций, таких как компания, которая должна иметь проекты, прибыль, назначение менеджеров, набора сотрудников и т. Д., И дочерняя компания также будет наследовать эти действия;
ClassCommonEmployeeExextends Employee // Подкласс 1: {intm_Managerno; // определить атрибут класса M_MANAGERNO, представляющий номер начальника сотрудников} ClassManagerEmployeExtends Employee // subclass 2: {intm_secretaryno; // define class attrube m_secretaryno, представлять секретарь}. Наследство атрибуции и прячутся
Хотя класс сотрудников является родительским классом, это не означает, что он имеет больше функций только потому, что это родительский класс. Напротив, в суб-аналогах больше функций, чем их родительские классы. Поскольку подкласс является расширением родительского класса, атрибуты и методы, которых нет родительского класса, добавляются (1) Подкласс не может получить доступ к частному члену родительского класса, но подкласс может получить доступ к общественности своего родительского класса.
(2) Защищенный доступ - это защитный промежуточный уровень между государственным и частным доступом.
(3) Поскольку унаследованные члены родительского класса не указаны в заявлении подкласса, эти члены существуют в подклассе.
Здесь мы должны различать наследство, перезагрузку и перегрузку, несколько запутанных концепций:
Только на концептуальном уровне метода эти три понятия могут быть легко запущены:
Метод наследование
Для объектов подкласса можно использовать методы из родительского класса. Даже если эти методы не четко определены в подклассе, они автоматически унаследованы от родительского класса.
Охват метода
Переопределение метода относится к: методу, который определяет метод с тем же именем для перезаписи родительского класса, который является реализацией полиморфных технологий. Когда метод родительского класса перезаписан в детском классе, обычно это версия класса дочернего класса, которая вызывает версию родительского класса и выполняет некоторую дополнительную работу.
Есть много вещей, чтобы отметить. Здесь я в основном упоминаю это и супер. Это есть в C ++ (и концепция похожа на концепцию в Java), но Super нет.
Это представляет сам текущий объект, и это представляет собой ссылку на текущий объект. Это можно понять как другое имя объекта. Это позволяет вам вызвать методы и свойства текущего объекта.
Например: this.getName () и getName () одинаковы в классе.
Super представляет объект прямых класса родительского класса текущего объекта и является перегрузкой метода эталонного метода родительского объекта класса текущего объекта.
Определение перегрузки: метод может быть определен с одним и тем же именем метода, но разными таблицами параметров (число, тип или порядок параметров в таблице параметров имеет разные значения), которые называются перегрузкой метода.
• Перегрузка: перегрузка происходит, когда несколько методов имеют одинаковое имя и содержат разные параметры. Компилятор должен выбрать, какой метод вызовать. Он выбирает правильный метод, сравнивая типы параметров в различных заголовках метода с типами значений, используемых в конкретных вызовах метода.
Полиморфизм позволяет обрабатывать существующие переменные и родственные классы в унифицированном стиле, что позволяет легко добавлять новые функции в систему. Здесь публикация информации, которую вы нашли в Интернете, может более четко прояснить полиморфизмы и проблемы наследования, которые требуют особого внимания в наследстве:
Полиморфизмы Java
Объектно-ориентированное программирование имеет три характеристики, а именно: инкапсуляция, наследование и полиморфизм.
Инкапсуляция скрывает внутренний механизм реализации класса, так что внутренняя структура класса может быть изменена, не затрагивая пользователя, защищая данные.
Наследование состоит в том, чтобы повторно использовать код родительского класса при подготовке к реализации полиморфизма. Так что же такое полиморфизм?
Перезагрузка, перегрузка, перегрузка и динамическое соединение составляют полиморфизм. Одна из причин, по которой Java представила концепцию полиморфизма, заключается в том, что он отличается от C ++ с точки зрения наследования классов. Последнее обеспечивает множественное наследство, которое приносит ему очень мощные функции, но сложные отношения наследования также приводят к большей проблеме разработчикам C ++. Чтобы избежать рисков, Java допускает только единое наследство, и существует связь между производными классами и базовыми классами (то есть «кошки»-это «животное»). Хотя это обеспечивает простоту и ясность отношений наследования, это неизбежно будет иметь большие функциональные ограничения. Поэтому Java представила концепцию полиморфизма, чтобы восполнить этот недостаток. Кроме того, абстрактные классы и интерфейсы также являются важными средствами для решения ограничений единичных правил наследования. В то же время полиморфизм также является сущностью объектно-ориентированного программирования.
Чтобы понять полиморфизм, вы должны сначала знать, что такое «восходящая трансформация».
Я определил подклассную кошку, которая наследует класс животных, и второй заключается в том, что первый является родительским классом. Я могу пройти
Cat C = новая кошка ();
Остановить объект кошки не сложно понять. Но когда я определяю это так:
Животное a = new Cat ();
Что это значит?
Это просто, это означает, что я определяю ссылку на тип животного на недавно созданный объект типа кошки. Поскольку CAT наследуется от своего родительского класса животного, ссылка на тип животного может указывать на объект типа кошки. Так какой смысл сделать это? Поскольку подклассы являются улучшением и расширением родительского класса, подклассы, как правило, более мощные, чем родительские классы, а их атрибуты более уникальны, чем родительские классы.
Определение ссылки на тип родительского класса указывает на объект, который подкласлен, может не только использовать мощные функции подкласса, но и извлекать общие черты родительского класса.
Следовательно, ссылка на тип родительского класса может вызвать все свойства и методы, определенные в родительском классе, и это беспомощно для методов, определенных в детском классе, но не в родительском классе;
В то же время метод в родительском классе может быть вызван ссылкой только на тип родительского класса, если он определен в родительском классе, но не переопределен в классе дочерних;
Для методов, определенных в родительском классе, если метод переписывается в классе дочернего класса, ссылка на тип родительского класса будет вызывать этот метод в детском классе, который является динамическим соединением.
Посмотрите на следующую программу:
Класс Отец {public void func1 () {func2 (); } // Это метод func2 () в родительском классе, поскольку метод переопределен в подклассе ниже // Таким образом, при вызове в ссылке типа родительского класса этот метод больше не будет действительным // заменить метод func2 (), переопределенный в подклассе Public void func2 () {System.out.println ("aaa"); }} класс Child расширяет отец {// func1 (int i) - это перегрузка метода func1 () // Поскольку этот метод не определен в родительском классе, его нельзя вызвать с помощью ссылки на тип родительского класса // Итак, в основном методе ниже Child.func1 (68) является неправильным публичным func1 (int i) {System.out.println ("bbb"); } // func2 () Переписывает метод func2 () в родительском классе отца // Если метод func2 () вызывается в ссылке на тип родительского класса, это должен быть метод, переписанный в подклассном пустоте func2 () {System.out.println ("ccc"); }} открытый класс PolymorphismTest {public static void main (string [] args) {отец ребенок = new Child (); child.func1 (); // Каким будет результат печати? }}Приведенная выше программа является очень типичным примером полиморфизма. Ребенок -ребенок -класс наследует отца родительского класса, перегружает метод родительского класса func1 () и перезаписывает метод родительского класса func2 (). Перегруженный func1 (int i) и func1 () больше не являются одним и тем же методом. Поскольку в родительском классе нет Func1 (int i), эталонный ребенок типа родительского класса не может вызвать метод func1 (int i). Если подкласс переопределяет метод func2 (), то эталонный ребенок типа родительского класса будет вызвать переписываемый func2 () в подклассе при вызове метода.
Итак, какие результаты будут печатать программу?
Очевидно, это должно быть "CCC".
Для полиморфизма его можно обобщить как:
(1) использовать ссылки типа родительского класса, чтобы указывать на объект подкласса (фактический объект);
(2) эта ссылка может только вызовать методы и переменные, определенные в родительском классе;
(3) Если метод в родительском классе переписывается в подклассе, то при вызове этого метода метод в подклассе будет вызван; (Динамическое соединение, динамический вызов)
(4) переменные не могут быть переписаны (переопределены). Концепция «переписать» предназначена только для методов. Если переменные в родительском классе «переписываются» в подклассе, во время компиляции будет сообщена ошибка.
Полиморфизм проходит через:
(1) Интерфейс и реализуйте интерфейс и перезаписывают несколько различных классов, которые охватывают один и тот же метод в интерфейсе (2) родительский класс и родительский класс и родительский класс, и перезаписывают несколько различных подклассов, которые охватывают один и тот же метод в родительском классе.
1. Основные понятия
Полиморфизм: отправьте сообщение в объект и позвольте объекту решить, на какое поведение ответить.
Динамические вызовы метода реализованы путем назначения ссылок на объект подкласса на ссылки на объект SuperClass.
Этот механизм AVA следует принципу: когда объект SuperClass относится к переменной для обозначения объекта подкласса, тип ссылочного объекта, а не тип указанной переменной определяет, чей метод элемента называется, но вызываемый метод должен быть определен в суперклассе, то есть метод, охваченный подклассом.
(1) Если A является ссылкой на класс A, то A может указывать на экземпляр класса A или на подкласс класса A.
(2) Если a является ссылкой на интерфейс A, то необходимо указывать на экземпляр класса, который реализует интерфейс A.
Механизм реализации полиморфизма Java
Текущий механизм реализации JVM Sun, ссылка на экземпляр класса является указателем на ручку, которая является парой указателей:
Указатель указывает на таблицу, и на самом деле эта таблица также имеет два указателя (один указатель указывает на таблицу методов, содержащую объект, и другой указатель на объект класса, указывающий тип, к которому принадлежит объект);
Другой указатель указывает на кусок памяти, выделяемый от кучи Java.
Суммировать
(1) Динамические вызовы метода реализованы путем назначения ссылок на объект подкласса на ссылки на объект Superclass.
Defivedc c2 = new drevivedc (); BaseClass A1 = C2; // базовый класс BaseClass, DEFIVEDC - это a1.play () унаследован от Baseclass; //play() is defined in BaseClass and DerivedC, that is, the subclass overrides the method
分析:
* 为什么子类的类型的对象实例可以覆给超类引用?
自动实现向上转型。通过该语句,编译器自动将子类实例向上移动,成为通用类型BaseClass;
* a.play()将执行子类还是父类定义的方法?
子类的。在运行时期,将根据a这个对象引用实际的类型来获取对应的方法。所以才有多态性。一个基类的对象引用,被赋予不同的子类对象引用,执行该方法时,将表现出不同的行为。
在a1=c2的时候,仍然是存在两个句柄,a1和c2,但是a1和c2拥有同一块数据内存块和不同的函数表。
(2)不能把父类对象引用赋给子类对象引用变量
BaseClass a2=new BaseClass(); DerivedC c1=a2;//出错
在java里面,向上转型是自动进行的,但是向下转型却不是,需要我们自己定义强制进行。
c1=(DerivedC)a2; 进行强制转化,也就是向下转型.
(3)记住一个很简单又很复杂的规则,一个类型引用只能引用引用类型自身含有的方法和变量。
你可能说这个规则不对的,因为父类引用指向子类对象的时候,最后执行的是子类的方法的。
其实这并不矛盾,那是因为采用了后期绑定,动态运行的时候又根据型别去调用了子类的方法。而假若子类的这个方法在父类中并没有定义,则会出错。
例如,DerivedC类在继承BaseClass中定义的函数外,还增加了几个函数(例如myFun())
分析:
当你使用父类引用指向子类的时候,其实jvm已经使用了编译器产生的类型信息调整转换了。
这里你可以这样理解,相当于把不是父类中含有的函数从虚拟函数表中设置为不可见的。注意有可能虚拟函数表中有些函数地址由于在子类中已经被改写了,所以对象虚拟函数表中虚拟函数项目地址已经被设置为子类中完成的方法体的地址了。
(4)Java与C++多态性的比较
jvm关于多态性支持解决方法是和c++中几乎一样的,
只是c++中编译器很多是把类型信息和虚拟函数信息都放在一个虚拟函数表中,但是利用某种技术来区别。
Java把类型信息和函数信息分开放。Java中在继承以后,子类会重新设置自己的虚拟函数表,这个虚拟函数表中的项目有由两部分组成。从父类继承的虚拟函数和子类自己的虚拟函数。
虚拟函数调用是经过虚拟函数表间接调用的,所以才得以实现多态的。
Java的所有函数,除了被声明为final的,都是用后期绑定。
1个行为,不同的对象,他们具体体现出来的方式不一样,
比如: 方法重载overloading 以及方法重写(覆盖)override
class Human{ void run(){输出人在跑} } class Man extends Human{ void run(){输出男人在跑} } 这个时候,同是跑,不同的对象,不一样(这个是方法覆盖的例子) class Test{ void out(String str){输出str} void out(int i){输出i} }这个例子是方法重载,方法名相同,参数表不同
ok,明白了这些还不够,还用人在跑举例
Human ahuman=new Man();
这样我等于实例化了一个Man的对象,并声明了一个Human的引用,让它去指向Man这个对象意思是说,把Man这个对象当Human看了.
比如去动物园,你看见了一个动物,不知道它是什么, "这是什么动物? " "这是大熊猫! "
这2句话,就是最好的证明,因为不知道它是大熊猫,但知道它的父类是动物,所以,
这个大熊猫对象,你把它当成其父类动物看,这样子合情合理.
这种方式下要注意new Man();的确实例化了Man对象,所以ahuman.run()这个方法输出的是"男人在跑"
如果在子类Man下你写了一些它独有的方法比如eat(),而Human没有这个方法,
在调用eat方法时,一定要注意强制类型转换((Man)ahuman).eat(),这样才可以...
对接口来说,情况是类似的...
Пример:
package domain; //Define superA class superA { int i = 100; void fun(int j) { j = i; System.out.println("This is superA"); } } //Define superA subclass subB class subB extends superA { int m = 1; void fun(int aa) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subB"); } } //Define superA subC class subC extends superA { int n = 1; void fun(int cc) { System.out.println("This is subC"); } } class Test { public static void main(String[] args) { superA a = new superA(); subB b = new subB(); subC c = new subC(); a = b; a.fun(100); a = c; a.fun(200); }} /*
* 上述代码中subB和subC是超类superA的子类,我们在类Test中声明了3个引用变量a, b,
* c,通过将子类对象引用赋值给超类对象引用变量来实现动态方法调用。也许有人会问:
* "为什么(1)和(2)不输出:This is superA"。
* java的这种机制遵循一个原则:当超类对象引用变量引用子类对象时,
* 被引用对象的类型而不是引用变量的类型决定了调用谁的成员方法,
* 但是这个被调用的方法必须是在超类中定义过的,
* 也就是说被子类覆盖的方法。
* 所以,不要被上例中(1)和(2)所迷惑,虽然写成a.fun(),但是由于(1)中的a被b赋值,
* 指向了子类subB的一个实例,因而(1)所调用的fun()实际上是子类subB的成员方法fun(),
* 它覆盖了超类superA的成员方法fun();同样(2)调用的是子类subC的成员方法fun()。
* 另外,如果子类继承的超类是一个抽象类,虽然抽象类不能通过new操作符实例化,
* 但是可以创建抽象类的对象引用指向子类对象,以实现运行时多态性。具体的实现方法同上例。
* 不过,抽象类的子类必须覆盖实现超类中的所有的抽象方法,
* 否则子类必须被abstract修饰符修饰,当然也就不能被实例化了
*/
以上大多数是以子类覆盖父类的方法实现多态.下面是另一种实现多态的方法-----------重写父类方法
JAVA里没有多继承,一个类之能有一个父类。而继承的表现就是多态。一个父类可以有多个子类,而在子类里可以重写父类的方法(例如方法print()),这样每个子类里重写的代码不一样,自然表现形式就不一样。这样用父类的变量去引用不同的子类,在调用这个相同的方法print()的时候得到的结果和表现形式就不一样了,这就是多态,相同的消息(也就是调用相同的方法)会有不同的结果。举例说明:
//Premary class public class Father{ //The parent class has a method to hit the child public void hitChild(){ } } //Subclass 1 public class Son1 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("Why hit me? What I did wrong!"); } } //Subclass 2 public class Son2 extends Father{ //Rewrite the method to hit the child public void hitChild(){ System.out.println("I know I'm wrong, stop hitting it!"); } } //Subclass 3 public class Son3 extends Father{ //Rewrite the parent class hits the child method public void hitChild(){ System.out.println("I run, you can't hit!"); } } //Test class public class Test{ public static void main(String args[]){ Father father; father = new Son1(); father.hitChild(); father = new Son2(); father.hitChild(); father = new Son3(); father.hitChild(); }}都调用了相同的方法,出现了不同的结果!这就是多态的表现!
import java.io.*;class Super{ Super(){ System.out.println("This is super class!"); } void method(){ System.out.println("Super's method"); }}class Sub extends Super{ Sub(){ super(); System.out.println("/n/t:and here is the child"); } void method(){ System.out.println("child's method"); }}public class Super_Sub{ public static void main(String[] args){ Super sup=new Sub(); sup.method(); Sub child=(Sub)new Super();//Here, the actual allocated memory is Super, but Child is used to refer to it. This is "downward transformation" (the parent class impersonates a child class, because the subclass is down when drawing in UML), and it must be casted by child.method(); }}对于数据来说,继承是否为正确的设计可以用一个简单的规则来判断。“is-a”规则表明子类的每一个对象都是一个超类的对象。例如,每一个经理是一个员工。然而,只有经理类是员工类的子类才是有意义的。很明显,反过来就不行了――并不是每个员工都是经理。
还有一个明确叙述“is-a”规则的方法是替代原则。该原则规定无论何时,如果程序需要一个超类对象,都可以用一个子类对象来代替
动态绑定
理解调用一个对象方法的机制是非常重要的。下面具体介绍:Xf;
(1)编译器检查对象的声明类型和方法名。
(2)接着,编译器检查方法调用中的参数类型。如果在所有的叫做f的方法中有一个其参数类型同调用提供的参数类型最匹配,那么该方法就会被选择调用。这个过程称作超载选择。(静态)
(3)当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用同x所指向的对象的实际类型相匹配的方法版本。
...
如果类中没有写构造函数,那么系统会自动为该类提供一个默认构造函数,该构造函数将所有的实例字段初始化为默认值:
...
包用途:
Java允许把多个类收集在一起成为一组,称作包(package)。包便于组织任务,以及使自己的任务和其他人提供的代码库相分离。
标准Java库被分类成许多的包,其中包括java.1ang、java.util和java.net等等。标准Java包是分层次的。就像在硬盘上嵌套有各级子目录一样,可以通过层次嵌套组织包。所有的Java包都在Java和Javax包层次内
创建包
已经看到,已有的库,比如JavaAPI中的类和接口,可以导入到Java程序中。
Java API中的每一个类和接口属于一个特定的包。它包含一组相关联的类和接口,实际是对类和接口进行组织的目录结构。
例如,假定文件名是MyClass.java。它意味着在那个文件有一个、而且只能有一个public类。而且那个类的名字必须是MyClass(包括大小写形式):
packagemypackage;publicclass MyClass{……}创建可复用的类的步骤简要说明如下:
(1)定义一个public类。如果类不是public,它只能被同一包中的其他类使用。
(2)选择一个包名,并把package语句加到可复用的类的源代码文件中。
(3)编译这个类。这样,它就被放到适当的包目录结构中,以供编译器和解译器使用。
(4)把这个可复用的类导入到需要用它的程序中。现在就可以使用它了。
注意在Java语言中可以出现在类定义的括号外面的仅有两个语句,它们是package和import。
包引用---每个类名前加上完整的包名
例如,给出一个指向此包中的类的快捷方式。一旦使用import(导入)了以后,就不再需要给出完整的包名。
可以引入一个特定的类,也可以引入整个包。import语句要放在源文件的头部(但在所有package语句的下面)。例如,可以通过下面的语句引入在java.util包中的所有的类:
importjava.util.*;
然后,就可以使用
Datetoday=new Date();
而不需要在前面加上包名。也可以引入包中某个特定的类:
importjava.util.Date;
要把类放人一个包中,必须把此包的名字放在源文件头部,并且放在对包中的类进行定义的代码之前。例如,在文件Employee.java的开始部分如下:
packagecom.horstmann.corejava;publicclass Employee{……}把包中的文件放入与此完整的包名相匹配的子目录中。例如,在包com.horstmann.corejava中的所有的类文件都必须放在子目录com/horstmann/core.java(Windows下的com/horstmann/corejava)下。这是最简单的一种方法
类被存储在文件系统的子目录中。类的路径必须与所在包名相匹配。
在前面的例子中,包目录com/horstmann/corejava是程序目录的一个子目录。然而这样安排很不灵活。一般,有多个程序需要访问包文件。为了使包可以在多个程序间共享,需要做以下事情:
1)把类放在一个或多个特定的目录中,比如/home/user/classdir。此目录是包树的基本目录。如果加入了类com.horstmann.corejava.Employee,那么此类文件必须位于子目录/home/user/classdir/com/horstmann/corejava下。
2)设置类路径。类路径是其子目录包含类文件的所有基本目录的集合。classpath
已经接触过public和private访问指示符。
被标记为Public的部件可以被任何类使用,而私有部件只能被定义它们的类使用。如果没有指定public或private,那么部件(即类、方法或变量)可以被同一个包中的所有方法访问。
Java API包
为了简化面向对象的编程过程,Java系统事先设计并实现了一些体现了常用功能的标准类,如用于输入/输出的类,用于数学运算的类,用于图形用户界面设计的类,用于网络处理的类等。这些系统标准类根据实现的功能不同,可以划分成不同的集合,每个集合是一个包,合称为类库。可以引用这些包,也可以创建自己的包。
Java的类库是系统提供的已实现的标准类的集合,是Java编程的API,它可以帮助开发者方便、快捷地开发Java程序
接口主要作用是可以帮助实现类似于类的多重继承的功能。在Java中,出于简化程序结构的考虑,不再支持类间的多重继承而只支持单重继承,即一个类至多只能有一个直接父类。然而在解决实际问题的过程中,仅仅依靠单重继承在很多情况下都不能将问题的复杂性表述完整,需要其他的机制作为辅助。
接口声明
Java中声明接口的语法如下:
[public] interface 接口名[extends 父接口名列表]{ //接口体;//常量域声明[public] [static] [final] 域类型域名=常量值; //抽象方法声明[public] [abstract] 返回值方法名(参数列表) [throw异常列表];}从上面的语法规定可以看出,定义接口与定义类非常相似,实际上完全可以把接口理解成为一种特殊的类,接口是由常量和抽象方法组成的特殊类
(1)接口中的属性都是用final修饰的常量,
(2)接口中的方法都是用abstract修饰的抽象方法,在接口中只能给出这些抽象方法的方法名、返回值和参数列表,而不能定义方法体,即仅仅规定了一组信息交换、传输和处理的“接口”
接口的实现
一个类要实现某个或某几个接口时,有如下的步骤和注意事项:
(1)在类的声明部分,用implements关键字声明该类将要实现哪些接口;
следующее:
class类名implements接口{ }(2)如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法,即为所有抽象方法定义方法体,而且方法头部分应该与接口中的定义完全一致,即有完全相同的返回值和参数列表;
(3)如果实现某接口的类是abstract的抽象类,则它可以不实现该接口所有的方法。
(4)一个类在实现某接口的抽象方法时,必须使用完全相同的方法头。
(5)接口的抽象方法,其访问限制符都已指定是public,所以类在实现方法时,必须显式地使用public修饰符。
краткое содержание:
多重继承是指一个子类继承多个父类。Java不支持多重继承,但Java提供了接口。
子类不能访问父类的private成员,但子类可以访问其父类的public,protected和包访问成员;要访问父类的包访问成员,子类一定要在父类的包内。
子类构造函数总是先调用(显式的或隐式地)其父类的构造函数,以创建和初始化子类的父类成员。
子类的对象可以当作其父类的对象对待,反之则不行(即向上转型)
protected访问是public和private访问之间一个保护性的中间层次。父类方法、子类方法和在同一个包内类的方法都能访问父类的protected成员,但其他方法均不能访问
一个子类对象引用可以隐式地转换成一个父类对象引用。使用显式的类型转换,可以把父类引用转换成子类引用。如果目标不是子类对象,将产生ClassCastException例外处理。