модуль 2 - урок 3-4 - ООП String.ppt
- Количество слайдов: 47
IT ШКОЛА SAMSUNG Модуль 2. Объектно-ориентированное программирование Три парадигмы ООП ( «три кита» ООП)
ПАРАДИГМЫ ООП или ТРИ КИТА ООП Три парадигмы, "три кита" объектно-ориентированного программирования это: 1. инкапсуляция, 2. наследование, 3. полиморфизм.
ИНКАПСУЛЯЦИЯ - пример Использование: Положить блюда, нажать нужные кнопочки Не нужно знать: Когда тарелка начинает крутиться, какой ток и напряжение нужно подать в том или ином режиме и др. Т. е. пользователь использует объект не задумываясь о его внутренней структуре
ИНКАПСУЛЯЦИЯ - пример
НАСЛЕДОВАНИЕ ПРИНЦИПЫ ü Дочерние классы наследуют методы родительского класса Если класс Shape обладает какой-то функциональностью, то его подклассы получают те же возможности
НАСЛЕДОВАНИЕ
ПОЛИМОРФИЗМ Благодаря наследованию вы можете гарантировать, что все классы, сгруппированные под одним родительским типом, содержат все методы этого типа
ПОЛИМОРФИЗМ ПРИНЦИПЫ ü Когда вы объявляете общий тип для группы классов, вы моете заменять родительский класс дочерним везде, где предполагается его присутствие
СОЗДАНИЕ КЛАССА Ключевое слово class, как начало описания нового типа данных class Имя_класса { Класс, который описывает прямоугольник: тип_поля 1 имя_поля 1; // имя_переменной 1 class Rect { тип_поля 2 имя_поля 2; // имя_переменной 2 double width; тип_результата 1 имя_метода 1 (параметры_метода 1) { double height; } тело_метода 1 } тип_результата 2 имя_метода 2 (параметры_метода 2) { тело_метода 2 } } Rect rect; // объявили переменную класса Rect под именем rect Теперь можно создавать переменные (объекты) этого типа: Имя_класса имя_объекта; !!! создание нового класса означает создание нового типа данных 9 Самого объекта в памяти еще нет!
СОЗДАНИЕ КЛАССА Можно явно указать, что объектная переменная ни на что не ссылается rect = null; Чтобы создать сам объект, необходимо использовать операцию new rect = new Rect(); Rect() - вызов метода класса без параметров и его имя совпадает с названием класса! Такой метод называется конструктором класса Конструктор определяет действия, выполняемые при создании объекта.
СОЗДАНИЕ КЛАССА Если в классе программистом не был задан конструктор, то Java автоматически создаст "конструктор по умолчанию", который проинициализирует все поля создаваемого объекта значениями по умолчанию, принятыми для каждого типа Java. В соответствии с официальной документацией Java для переменных различных типов определены следующие значения по умолчанию: Тип Значение по умолчанию byte, short, int, long, float, double 0 (в соответствующем формате представления) char 'u 0000' boolean false объекты и массивы null
СОЗДАНИЕ КЛАССА Почему переменные примитивных типов не требуют использование операции new? У таких типов значения хранятся непосредственно в переменных. Это позволяет языку обеспечить высокую скорость работы В переменных объектного типа, хранятся ссылки на динамическую область памяти, где операцией new было выделено место под хранение объекта со всеми его полями и ссылками на методы.
ОПИСАНИЕ ПОЛЕЙ КЛАССА class Rect { Rect rect 1 = new Rect(); rect 1. height = 10; double width; double height; } rect 1. width = 20; Rect rect 2 = new Rect(); rect 2. height = 10; Каждый объект имеет собственные значения полей. Данные одного объекта полностью отделены от данных rect 2. width = 20; другого объекта. System. out. println(rect 1 == rect 2); // ? rect 2 = rect 1; System. out. println(rect 1 == rect 2); // ? Что выведет исходный фрагмент на экран и почему? false true
ОПИСАНИЕ МЕТОДА В ПРОТОКОЛЕ КЛАССА тип_данных_которые_метод_вернет ИМЯ_МЕТОДА (список_параметров_метода){ операторы тела метода } Для вызова метода, как и для обращения к полю класса, нужно использовать операцию точка class Rect { double width; double height; System. out. println(rect 1. area()); double area() { return width * height; } } У данного метода нет параметров, потому что его параметрами являются ширина и высота самого объекта — прямоугольника
ПРИМЕР МЕТОДА С ПАРАМЕТРОМ // Увеличение в указанное число размеров прямоугольника void magnify(double koeff) { width *= koeff; rect 1. magnify(1. 5); height *= koeff; } Для вызова метода, описанного в классе, нужно обязательно указать объект, к которому применяется этот метод (исключение — статические методы, которые будут рассмотрены позже)
КЛАССЫ-ОБОЛЧКИ ПРИМИТИВНЫХ ТИПОВ Для того, чтобы с примитивными типами данных можно было работать так же, как с остальными-объектными, для каждого из них существует свой собственный класс-оболочка. Они инкапсулируют в себе эти простые типы и предоставляют широкий набор методов для работы с ними. Это очень часто применяется на практике Примитивный тип Соответствующий класс-оболочка byte Byte short Short int Integer long Long float Float double Double Примеры использования смотрим в Практической работе № 1
СТРОКИ - String В Java строки относятся к неизменяемым объектам (англ. immutable) - объектам, состояние которых не может быть изменено после создания. Т. е символы строковой переменной после ее создания поменять нельзя! String имя_строки="содержимое строки"; //рекомендуемая форма String имя_строки= new String("содержимое строки"); String hello 1 = "Здравствуйте!"; String hello 2 = new String("Здравствуйте!"); В результате выполнения этой строчки кода в памяти создается объект класса String, хранящий символы строки "Здравствуйте", а ссылка на него сохраняется в переменной hello 1/hello 2. При работе с объектами String, если требуется получить другую строку, используя символы имеющейся строки, нужно создать новую строку. При необходимости можно присвоить прежней переменной сылку на новую строку в памяти, но поменять строку в уже существующем объекте String нельзя. При необходимости менять символы именно имеющейся строки — используйте класс String. Buffer.
Строки - String В Java неизменяемые объекты (англ. immutable) получили широкое распространение. Они позволяют обеспечить безопасность при многопоточном выполнении программ, что характерно для приложений под Android. С понятием многопоточности мы познакомимся позже в рамках данного модуля.
СТРОКИ – String – ОСНОВНЫЕ ОПЕРАЦИИ И МЕТОДЫ + Операция конкатенации — две строки сливаются в одну. К символам первого аргумента (того, что стоит до "плюса") приписываются справа символы второго аргумента (того, что стоит после "плюса"). Если при этом один из аргументов — не строка, а другой тип данных, он преобразуется в строковое представление. boolean equals(Object object) Метод сравнения двух строк — той строки, к которой применяется и строки, указанной в качестве параметра. Например: String s 1 = new String("Ваня учится в IT ШКОЛЕ SAMSUNG"); String s 2 = new String("Ваня учится в IT ШКОЛЕ SAMSUNG"); System. out. println(s 1. equals(s 2)); System. out. println(s 1 == s 2); На экран будет выведено: true false Метод equals позволяет сравнивать содержимое строк, что не позволяет сделать операция ==.
СТРОКИ – String – ОСНОВНЫЕ ОПЕРАЦИИ И МЕТОДЫ int length() Вычисляет длину строки в символах. Для предыдущего примера результат s 1. length() будет равен 28. char. At(int index) Выдает символ, находящийся в строке на позиции номер index. Номера символов считаются с нуля (как в массивах). Например, s 1. char. At(3) будет равен 'я'. int compare. To(String another. String) Сравнивает две строки по буквам с учетом регистра и языка. Возвращает целое число, показывающее, является ли эта строка больше (результат> 0), равный (результат = 0), или менее (результат <0) аргумент.
КОНСТРУКТОРЫ КЛАССОВ При создании объекта отводится память для хранения полей объектов и ссылок на методы. При этом поля объекта автоматически инициализируются значениями по умолчанию, принятыми в Java. Чтобы инициализировать объект по своим правилам используют специальные функции-конструкторы. Свойства конструктора: ü обязательно имеет имя, совпадающее с названием класса; ü вызывается при создании объекта; ü в отличие от метода не имеет явным образом определённого типа возвращаемых данных и не наследуется.
КОНСТРУКТОРЫ КЛАССОВ //Класс “Натуральная дробь” public class Fraction { int numerator; // Числитель int denominator; // Знаменатель } Компилятор автоматически создает конструктор, не имеющий параметров (даже если мы его явно не написали). Переменные экземпляра всегда получают значения по умолчанию. Если вы явно не присвоите переменной значение или не вызовете сеттер, она все равно будет хранить значение! Целые 0 Вещественные 0. 0 Булевые false Ссылки null ПЛОХО! Конструктор по умолчанию задаст знаменателю значение 0 (значение по умолчанию для типа int), а нас такой вариант не устраивает, потому что мы можем получить ошибку деления на ноль.
КОНСТРУКТОРЫ КЛАССОВ //Класс “Натуральная дробь” public class Fraction { int numerator; // Числитель int denominator; // Знаменатель public Fraction() { denominator = 1; } } Собственный конструктор ИЛИ без собственного конструктора public class Fraction { int numerator; int denominator = 1; } // Числитель // Знаменатель Собственный конструктор МОЖНО не записывать
КОНСТРУКТОРЫ КЛАССОВ Если необходимо предоставить возможность совместить создание объекта и инициализацию его полей собственными значениями, то тогда используют конструктор с параметрами. public class Fraction { int numerator;// Числитель int denominator = 1;// Знаменатель public Fraction(int numerator, int denominator) { if (denominator == 0) { System. out. println("Denominator can't be zero. Choose another one. "); return; } //this. name- ссылается на объект this. numerator = numerator ; //текущего класса this. denominator = denominator ; } используя this, можно легко различить к чему мы обращаемся: к одноименному параметру или полю объекта. } Оператор return также, как в методе, завершает выполнение конструктора. Как правило, его используют для прекращения инициализации объекта в нештатных ситуациях.
ОСОБЕННОСТИ КОНСТРУКТОРОВ ü ü не могут напрямую вызываться (необходимо использовать ключевое слово new) вызываются только один раз - при создании объекта в памяти; называются так же, как называется класс; они ничего не возвращают (на самом деле они всегда возвращают this). В конструкторе как правило инициализируют поля, без которых существование объекта не имело бы смысла, т. е. обязательные атрибуты. Конструктор дроби защищен от неправильного ввода знаменателя, но ничто не мешает установить его в ноль после создания объекта. Исправить это нам поможет один из принципов ООП - инкапсуляция.
IT ШКОЛА SAMSUNG Модуль 2. Объектно-ориентированное программирование Перегрузка методов. Инициализация данных класса
ПЕРЕГРУЗКА МЕТОДОВ – это возможность языка программирования создавать несколько методов с одинаковыми именами, но с другим набором параметров (сигнатурой) Сигнатура метода в Java - это совокупность имени метода с набором параметров. Т. е. тип возвращаемого значения не входит в сигнатуру, а порядок следования параметров и их типы - входит.
ПЕРЕГРУЗКА МЕТОДОВ void pr(double a) { System. out. println(a); Пример использования метода: } int a = 5; // 1 -я перегрузка int [] m = {1, 2, 8, 3} void pr(String a) { String s = "Мир"; System. out. println(a); pr(a) //работает исходный метод } pr(a + s); //сработает 1 -я перегрузка и будет выведено: 5 Мир // 2 -я перегрузка pr(m); //сработает 2 -я перегрузка и будет выведено: 1 2 8 3 void pr(int[] a) { for (int i=0; i<a. length; i++) { pr(m + a); // ошибка System. out. print(a[i]+" ") } System. out. println(); } Статические методы могут перегружаться нестатическими и наоборот – без ограничений. При вызове перегруженных методов следует избегать ситуаций, когда компилятор будет не в состоянии выбрать тот или иной метод.
ПРИМЕР ВЫЗОВА ПЕРЕГРУЖЕННЫХ МЕТОДОВ package chapt 1; public class Number. Info { public static void view. Num(Integer i) {// 1 System. out. printf("Integer=%d%n", i); } public static void view. Num(int i) {// 2 System. out. printf("int=%d%n", i); } public static void view. Num(Float f) {// 3 System. out. printf("Float=%. 4 f%n", f); } public static void view. Num(Number n) {// 4 System. out. println("Number=" + n); } public static void main(String[] args) { Number[] num = { new Integer(7), 71, 3. 14 f, 7. 2 }; for (Number n : num) view. Num(n); view. Num(new Integer(8)); view. Num(81); view. Num(4. 14 f); выбор варианта перегруженного метода view. Num(8. 2); происходит на этапе компиляции } }
ПЕРЕГРУЗКА МЕТОДОВ - ПРАВИЛА ü не использовать сложных вариантов перегрузки; ü заменять при возможности перегруженные методы на несколько разных методов. ü избегайте произвольного изменения имен параметров в перегрузках. Если параметр в одной перегрузке представляет то же входное значение, что и параметр в другой перегрузке, параметры должны иметь одинаковые имена. ü будьте последовательны при упорядочении параметров в перегружаемых членах. Параметры с одинаковыми именами должны находиться во всех перегрузках на одном и том же месте.
КОНСТРУКТОР ПО УМОЛЧАНИЮ конструктор по умолчанию является единственным конструктором без аргументов, который используется для создания объекта. Если вы создаете класс, который не имеет конструкторов, компилятор автоматически создаст конструктор по умолчанию вместо вас. class Bird { Строка new Bird(); создает новый объект и вызывает конструктор по умолчанию, даже несмотря на то, что он не int i; был явно определен. } public class Default. Constructor { public static void main(String[] args) { Bird nc = new Bird(); // по умолчанию! } }
КОНСТРУКТОР ПО УМОЛЧАНИЮ если вы определили любой конструктор (с аргументами или без них), компилятор не будет синтезировать его за вас class Bush { Bush(int i) {} Bush(double d) {} } Теперь, если вы скажете “new Bush(); ”, компилятор заявит, что он не может найти соответствующий конструктор.
КОНСТРУКТОР ПО УМОЛЧАНИЮ Таким образом ключевое слово this, которое может использоваться только внутри метода, содержит ссылку на объект, который вызвал метод. Вы можете трактовать эту ссылку, как и любой другой объект. Методы одного и того же класса вполне могут вызывать друга и без использования this. class Apricot { void pick() { /*. . . */ } void pit() { pick(); /*. . . */ } } Внутри pit( ) можно было бы написать this. pick( ), но в этом нет необходимости. Компилятор делает это автоматически.
КОНСТРУКТОР ПО УМОЛЧАНИЮ Наиболее часто this используется в инструкции return, когда необходимо вернуть явно ссылку на текущий объект // Использование ключевого слова "this" в return public class Leaf { int i = 0; Leaf increment() { i++; return this; } void print() { System. out. println("i = " + i); } public static void main(String[] args) { Leaf x = new Leaf(); x. increment(). print(); } } Поскольку в приведенном примере метод increment( ) через ключевое слово this возвращает ссылку на текущий объект возможно многократное увеличение поля i одного и того же объекта.
ВЫЗОВ ПЕРЕГРУЖЕННЫХ КОНСТРУКТОРОВ ЧЕРЕЗ THIS При определении перегруженных конструкторов зачастую для того, чтобы не дублировать код также используют ключевое слово this. В этом случае внутри одного конструктора можно вызвать другой. Компилятор, когда встречает вызов конструктора через this ищет соответствующий по сигнатуре перегруженный конструктор и выполняет его. Затем управление переходит на операторы, которые следуют за вызовом this(), т. е. продолжается выполнение исходного конструктора.
ВЫЗОВ ПЕРЕГРУЖЕННЫХ КОНСТРУКТОРОВ ЧЕРЕЗ THIS public class Person { private String first. Name; // Конструктор 4 private String last. Name; Person(String last. Name, String first. Name, char gender) { private char gender; this(last. Name, first. Name); //Вызывается конструктор 3 // m-male, f- female this. gender = gender; } // Конструктор 1 Person() { public void Print. Person() { //Вызывается конструктор 4 System. out. print(this. last. Name + " "); this("", '-'); System. out. print(this. first. Name + " "); } System. out. print(this. gender); // Конструктор 2 System. out. println(); Person(String last. Name) { } //Вызывается конструктор 4 this(last. Name, "", '-'); } } // Конструктор 3 Person(String last. Name, String first. Name) { this. first. Name = first. Name; this. last. Name = last. Name; ВАЖНО! При этом вызов конструктора this() должен быть } первым оператором в конструкторе.
ИНКАПСУЛЯЦИЯ И СПЕЦИФИКАТОРЫ ДОСТУПА Инкапсуляция означает, что данные объекта недоступны другим объектам непосредственно. Вместо этого они инкапсулируются — скрываются от прямого доступа извне. Инкапсуляция предохраняет данные объекта от нежелательного доступа, позволяя объекту самому управлять доступом к своим данным. Поля и методы объекта могут обладать различной степенью открытости (или доступности). Открытые члены класса составляют внешний интерфейс объекта. Это та Функциональность, которая доступна другим классам. Закрытыми обычно объявляются все свойства класса, а также вспомогательные методы, которые являются деталями реализации и от которых не должны зависеть другие части системы.
СПЕЦИФИКАТОРЫ ДОСТУПА Если модификатор доступа не указан явно, то подразумевается уровень доступа package. Это значит, что класс будет доступен только для классов, которые находятся в том же пакете. Также этот модификатор называют модификатором доступа по умолчанию (default). Уровень доступа private используется для сокрытия методов или переменных класса от других классов, т. е. они доступны только внутри класса. Если необходимо получить доступ к этим переменным, то используют специальные методы: getter и setter, которые позволяют включить дополнительную логику перед тем как вернуть либо присвоить значение. Protected. Данный модификатор нужен для видимости членов класса в самом классе и в его наследниках. Модификатор доступа public означает, что метод или поле видны и доступны любому классу.
СПЕЦИФИКАТОРЫ ДОСТУПА
СПЕЦИФИКАТОРЫ ДОСТУПА Модификаторы Область доступа Класс Поле Метод Конструктор Блок private Только из данного класса - + + + - без модификатора Для всех классов данного пакета + + + protected Классы данного пакета и потомки - + + + - public Без ограничений + + -
Сеттеры и геттеры public class Fraction { private int numerator;// Числитель private int denominator = 1;// Знаменатель public Fraction(int numerator, int denominator) { if (denominator == 0) { System. out. println("Denominator can't be zero. Choose another one. "); return; } // знак храним в числителе this. numerator = numerator * (denominator < 0 ? 1: 1); // знаменатель всегда положительный this. denominator = Math. abs(denominator); } //продолжение следует
СПЕЦИФИКАТОРЫ ДОСТУПА // окончание public int get. Numerator() { return numerator; } public int get. Denominator() { return denominator; } public void set. Numerator(int numerator) { this. numerator = numerator; } public void set. Denominator(int denominator) { if (denominator == 0) { System. out. println("Denominator can't be zero. Choose another one. "); return; } this. denominator = denominator; } }
СТАТИЧЕСКИЕ ПОЛЯ И МЕТОДЫ КЛАССА Иногда бывает нужно, чтобы поле класса имело одинаковое значение для всех объектов данного класса и при изменении значения поля все методы видели новое значение. В таком случае её нужно объявить с ключевым словом static (статический). Такое поле будет общим для всех экземпляров класса. Если объявление атрибута класса или метода начинается со слова static, то не обязательно создавать экземпляр класса, чтобы их использовать. Обращение в данном случае происходит через Имя. Класса. поле или Имя. Класса. метод(). В языке Java модификатор static применяется к внутренним классам, методам, полям и логическим блокам. И тогда мы получаем соответственно статические классы, статические методы, статические поля и статические блоки инициализации. В языке Java, в отличие, например, от Паскаля или С, отсутствуют глобальные переменные и константы в привычном смысле. Но так как это остается необходимым, применяют статические поля.
СТАТИЧЕСКИЕ ПОЛЯ И МЕТОДЫ КЛАССА Наиболее часто статические поля используют как константы. Например, библиотечный класс Math имеет статическую константу PI public class Math { . . . public static final double PI = 3. 14159265358979323846; . . . } С одной стороны модификатор доступа public позволяет использовать константу везде, а с другой стороны, добавив слово final, мы гарантируем, что это поле невозможно изменить. Применять общедоступные статические поля без final очень опасно, так как любой объект сможет изменить их значения
СТАТИЧЕСКИЕ ПОЛЯ И МЕТОДЫ КЛАССА При использовании статических методов есть ограничения. Вы НЕ можете получить доступ к НЕ статическим членам класса, внутри статического метода. Результатом компиляции приведенного ниже кода будет ошибка: public class Counter{ private int count; public static void main(String args[]){ System. out. println(count); } } //compile time error Это одна из наиболее распространённых ошибок допускаемых программистами Java, особенно новичками. Так как метод main статичный, а переменная count нет, в этом случае метод println, внутри метода main выбросит “Compile time error”. Кроме этого статичной не может быть локальная переменная.
СТАТИЧЕСКИЕ ПОЛЯ И МЕТОДЫ КЛАССА Представим, что вы пишите игру и для статистики нужно подсчитывать количество созданных персонажей. В таком случае вы можете завести статическое поле count, причем сделать его private, чтобы никто не мог накрутить счетчик. Увеличение счетчика будет происходить в конструкторе. Код выглядел бы примерно так: public class Person { private static int count; public Person() { count++; // дальнейшая логика. . . } public static int get. Count() { return count; } }
ПРАКТИЧЕСКАЯ РАБОТА № 1 47
модуль 2 - урок 3-4 - ООП String.ppt