Определение классов и методов Вызов метода

Определение классов и методов
Вызов метода
Вызов метода — это своего рода "приказ" объекту выполнить конкретное действие (описанное операторами в теле метода), используя конкретные данные, содержащиеся в вызывающем объекте.
Определение классов и методов
Вызов метода
Метод, определенный в классе, обычно вызывается с использованием объекта класса.
Такой объект называется вызывающим объектом (calling object).
Point p = new Point();
p.init(10,12); // p.x ==10, p.y ==12
p.init (x1, y1); // p.x ==x1, p.y ==y1
p.init (x1+x2, y2^3);

Определение классов и методов
В некоторых специальных случаях
(для статических методов)
вместо объекта класса в вызове метода используется имя самого класса:
Ans = Math.max (2,3);
S1 = String.valueOf(567.56);
Внутри класса, в котором описан метод, он может вызываться по имени в других методах этого класса.

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

Определение классов и методов
public class BankAccount
{
public void showNewBalance () {
double newAmount = amount + (rate/100.0)
*amount;
System.out.println ("После начисления
процентов на счету стало $"
+ newAmount) ;
}
public double amount;// перем. реализации
public double rate; // перем. реализации
}

Определение классов и методов
public class LocalVariablesDemoProgram {
public static void main(String[] args){
BankAccount myAccount = new BankAccount();
myAccount.amount = 100.00;
myAccount.rate = 5;
double newAmount = 10000.00;//лок. в main
myAccount.showNewBalance();
System.out.println("Моя мечта - иметь
на счету в банке $" + newAmount);
}
}

Определение классов и методов
В Java запрещается иметь одноименные переменные внутри одного определения метода.
Переменные, объявленные в блоке, являются локальными по отношению к этому блоку и исчезают, когда выполнение этого блока завершается.
Блок – составной оператор с описаниями.
Переменную нельзя использовать вне блока, в котором она описана.

Определение классов и методов
При обращении к методу формальные параметры заменяются на фактические (реальные).
Если формальные параметры имеют примитивные типы, то при замене формальных параметров на фактические используется механизм вызова по значению (call by value)
Формальный параметр, используемый в определении метода, является локальной переменной, которая инициализируется значением фактического параметра

Определение классов и методов
Между формальными и фактическими параметрами устанавливается взаимнооднозначное соответствие.
В случае рассогласования по типу осуществляется автоматическое преобразование типов:
Byte->short->int->long->float->double

Определение классов и методов
Example.
public double distance(float x1, float y1,
float x2, float y2) {
float xdiff, ydiff;
xdiff = x1 – x2;
ydiff = y1 – y2;
return Math.sqrt(xdiff^2 + ydiff^2);
}

Определение классов и методов
…
int x3, x4, y3,y4;
…
double dist = distance (x3,y3,x4,y4);
…

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

Определение классов и методов
Для доступа к таким переменным за пределами класса должны быть использованы специальные public методы:
Аксессорный метод для чтения
(accessor method) – get…
Мутаторный метод для записи (mutator method) – set…
т.е. сам программист планирует и управляет доступом к закрытым переменным

Определение классов и методов
public class MyClass{
private String name; //Определение //переменных реализации
private int age;
private String address;
….

Определение классов и методов
// мутатор
public void setNewFields (String newName,
int newAge, String newAddress){
name = newName;
if (newAge >0)
age = newAge;
else {System.out.printin("ОШИБКА:
использование отрицательного
возраста”);
System.exit(0); }
address = newAddress;
}

Определение классов и методов
// аксессоры
public String getName ( ) {
return name;
}
public int getAge( ) {
return age;
}
public String getAddress( ) {
return address;
}
}

Определение классов и методов
Обращение к методам:
public class DemoClass {
…public static void main …{
MyClass cl1= new MyClass ( );
сl1.setNewFields (“A.Шварценеггер’’, 60,
“Los Angeles,California”);
…
System.out.println (cl1.getName (),cl1.getAge(),
cl1.getAddress() );
…

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

Определение классов и методов
Основные правила создания хорошо инкапсулированных классов:
Перед определением класса разместить комментарий, как программист должен представлять себе данные и методы класса (в терминах предметной области)
Все переменные реализации в классе должны объявляться с использованием модификатора private
Предусмотреть public-методы аксессора и мутатора для чтения и изменения данных в объекте

Определение классов и методов
Предусмотреть другие public-методы, необходимые программисту для обработки данных в классе (методы ввода-вывода, например)
Перед заголовком каждого public-метода поместите комментарий, как использовать данный метод
Сделать все вспомогательные методы закрытыми

Определение классов и методов
Параметры типа класса (ссылки).
В переменной типа класса хранится не объект этого класса, а адрес области(ссылка – reference) памяти, в которой расположен объект
Все типы классов являются ссылочными типами, но существуют ссылочные типы, которые не являются типами классов (массивы)

Определение классов и методов
Формальные параметры типа класса обрабатываются на основе другого механизма замены (call by reference).
Формальный параметр типа класса –
локальная переменная , в которой хранится адрес объекта этого класса.
При обращении к методу параметр инициализируется адресом соответствующего фактического параметра, задаваемого в вызове метода,т.е.
Формальный параметр служит в качестве альтернативного имени для объекта, заданного аргументом в вызове метода

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

Определение классов и методов
Example.
Class Point { // описание класса
public double x,y;
public double distance (Point that) {
double xdiff, ydiff;
xdiff = x-that.x;
ydiff = y – that.y;
return Math.sqrt(xdif^2 + ydiff^2);
}
}

Определение классов и методов
Class MyClass {
public static void main …{
Point lowerLeft = new Point ( );
Point upperRight = new Point ( );
lowerLeft.x = 0.0;
lowerLeft.y = 0.0;
upperRight.x = 1280.0;
upperRight.y = 1024.0;
double dist = lowerLeft.distance(upperRight);
....
}
}

Определение классов и методов
Параметр this.
При определении метода в качестве имени вызывающего объекта можно использоваться ссылка на текущий объект (имя вызывающего объекта) - this.
Оно будет заменено именем объекта, вызывающего метод: (для класса Point)
public void move(double x, double y){
this.x = х;//имена параметров скрывают
this.y = y;//имена полей
}

Определение классов и методов
this чаще всего используется для передачи ссылки на текущий объект в качестве параметра для других методов. Предположим, в методе необходимо пополнить список объектов, ожидающих обслуживания.
Service.add(this);

Определение классов и методов
this неявно добавляется в начало каждой ссылки на поле или метод,
если программист не указал ссылку на другой объект.
Например,
class Name {
public String str;
Name() {
str = “”;
}
}
равносильно следующему: this.str = “”;

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

Определение классов и методов
// Простой пример рекурсии.
class Factorial {
// это рекурсивная функция
int fact (int n) {
int result;
if (n==1) return 1;
result = fact(n-l) * n;
return result;
}
}

Определение классов и методов
class Recursion {
public static void main (String args[]) {
Factorial f = new Factorial ( ) ;
System.out.println( "Факториал 3
равен " + f.fact(3));
System.out.println( "Факториал 4
равен " + f.fact (4) ) ;
System.out.println( "Факториал 5
равен " + f.fact (5));
}
}

Определение классов и методов
Вывод этой программы:
факториал 3 равен 6
факториал 4 равен 24
факториал 5 равен 120

Статические методы и переменные
Иногда возникает потребность в методе, которому не нужно задавать какой-нибудь объект.
Например, все математические методы не нуждаются в объектах
В таких случаях можно определить метод как статический (static).
Статический метод определяется в классе, поэтому он является членом класса, но его можно вызвать, не используя никакого объекта.

Статические методы и переменные
В вызове статического метода вместо использования имени объекта обычно используется имя класса, в котором этот метод определен.
Статические методы иногда называются методами класса (class methods), они вызываются для целого класса, а не для каждого конкретного объекта, созданного на его основе.

Статические методы и переменные
Example.
/*Класс, содержащий статические методы для выполнения вычислений, связанных с окружностями.*/
public class CircleFirstTry {
public static final double PI = 3.14159;
public static double area (double radius){
return (PI*radius*radius) ;
}
public static double circumference(double
radius){
return (PI*(radius + radius));
}
}

Статические методы и переменные
public class CircleDemo{
public static void main(String[] args){
double radius;
System.out.println ("Введите радиус
круга в cм:");
radius =System.In.readLineDouble();
System.out.println ("Круг радиусом "
+ radius + " см");

Статические методы и переменные
System.out.println ("имеет площадь " +
CircleFirstTry.area(radius) +
" квадратных см");
System.out.println ("и длину окружности"
+
CircleFirstTry.circumference(radius)
+ " см.")
}
}

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

Статические методы и переменные
Example.
/**********************************************
Вызов нестатического метода внутри статического
***************************************************/
public class PlayCircle {
public static final double PI = 3.14159;
private double diameter;//перем.реализации
public void setDiameter(double newDiameter){
diameter = newDiameter;
}

Статические методы и переменные
public static double area(double radius){
return (PI*radius*radius);
}
public void showArea(){
System.out.println("Площадь равна " +
area(diameter/2));
}//вызов статического метода внутри
// нестатического

Статические методы и переменные
public static void areaDialog()
System.out.println("Введите диаметр
круга:");
double newDiameter =
System.in.readLineDouble();
PlayCircle с = new PlayCircle();
с.setDiameter(newDiameter);
с.showArea();//вызов нестатического метода
} // в статическом методе
}//end PlayCircle

Статические методы и переменные
public class PlayCircleDemo {
public static void main (String [] args) {
PlayCircle circle = new PlayCircle ();
circle. setDiameter (2) ;
System. out .println ("Если диаметр
круга равен 2,");
circle . showArea ( ) ;
System.out.println("А теперь выберите
сами значение диаметра.”)
PlayCircle.areaDialog();
}
}

Статические методы и переменные
- Диалог:
- Если диаметр круга равен 2,
- Площадь равна 3.14159
- А теперь выберите сами значение диаметра.
- Введите диаметр круга:
- 4
- Площадь равна 12.56636

Статические методы и переменные
B определении статического метода нельзя использовать переменную реализации или метод, который имеет явно или неявно заданный параметр this для вызывающего объекта.

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

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

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

Статические методы и переменные
Иногда возникает необходимость совместного использования переменной всеми объектами класса
Они называются переменными класса, т.е. переменными относящимися ко всему классу, в отличие от переменных, относящихся к его отдельным объектам и описываются как static
private static int numberOflnvocations = 0;
public static Point origin = new Point ( );

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

Статические методы и переменные
public class StaticDemo{ private static int numberOfInvocations =0;
public static void main(String[] args)
int i;
StaticDemo object1 = new StaticDemo();
for (i = 1; i <=10 ; i++)
object1.outPutCountOfInvocations();
StaticDemo object2 = new StaticDemo();
for (i = 1; i <=10 ; i++)
object2.justADemoMethod();

Статические методы и переменные
System.out.println("Общее количество вызовов = " + numberSoFar());
}
public void justADemoMethod() {
numberOfInvocations++;….
}
public void outPutCountOfInvocations () {
numberOf Invocations++;
System.out.println(numberOflnvocations);
}
public static int numberSoFar () {
numberOf Invocations++;
return numberOflnvocations;
}
}

Статические методы и переменные
Результат
1
- 2
- 3
- 4
- …
- 10
- Общее кол-во вызовов = 21

Перегрузка метода (overloading)
Наличие двух или больше определений методов под одним и тем же именем внутри одного и того же класса называется перегрузкой метода.
Чтобы перегрузка успешно работала, необходимо предусмотреть, чтобы различные определения методов с одинаковыми именами имели какие-нибудь различные параметры.

Перегрузка метода (overloading)
/************************************** Это класс для иллюстрации перегрузки.
**************************************/
public class Statistician{
public static void main(String[] args){
double average1=Statistician.average(40.0,
50.0);
double average2 = Statistician.average(1.0,
2.0, 3.0);
char averages = Statistician.average('a', 'с');
…
}

Перегрузка метода (overloading)
public static double average (double first,
double second) {
return ((first + second) /2.0) ;
}
public static double average (double first,
double second, double third){
return ( (first + second + third) /3.0);
}

Перегрузка метода (overloading)
public static char average (char first, char
second)
return (char) (((int)first + (int)second)/2);
}

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

Перегрузка метода (overloading)
Java всегда старается использовать средство перегрузки до автоматического преобразования типов.
Если Java в состоянии найти определение метода, в котором есть совпадение типов аргументов, то воспользуется именно этим определением,
в противном случае запускается механизм автоматического преобразования типов

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

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

Конструкторы
Назначение конструкторов во многом совпадает с назначением методов set в нашем определении класса
Но в отличие от методов set, конструкторы вызываются автоматически при создании объекта с помощью оператора new.
Конструкторы имеют то же имя, что и сам класс
При определении конструктора не нужно указывать тип возвращаемого значения, и void также опускается.

Конструкторы
/**************************************
Класс для сбора основных данных о домашних
*животных: имя, возраст и вес.
**************************************************/
public class PetRecord {
private String name;
private int age; //в годах
private double weight; //в кг

Конструкторы
public PetRecord (String initialName,
int initialAge,
double initialWeight) {
name = initialName;
if ((initialAge < 0) || (initialWeight < 0))
{
System.out.println (
"Ошибка: отрицательный возраст или вес.")
System. exit (0) ;}
else {age = initialAge; weight = initialWeight;}
}

Конструкторы
public void set (String newName, int
newAge, double newWeight){
// тело как в предыдущем конструкторе
…
}
public PetRecord (String initialName) {
name = initialName;
age =0;
weight =0;
}

Конструкторы
public PetRecord (int initialAge) {
name = "Пока без имени";
weight = 0;
if (initialAge < 0)
{System.out.println("Ошибка:
отрицательный возраст.");
System.exit(0);}
else age = initialAge;
} ……

Конструкторы
public PetRecord ( ) {
name = “Пока без имени”;
age =0;
weight =0;
}
}

Конструкторы
//вызовы конструкторов
…public static void main… {
PetRecord cow = new PetRecord (“Qween” ,
10, 400);
…
PetRecord fish = new PetRecord(“Titanic”,
2, 0.2);…
PetRecord newBorn= new PetRecord();…
}

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

Конструкторы (зачем)
Некоторые классы не обладают разумным начальным состоянием, если не передать им параметры
При конструировании объектов некоторых видов передача исходного состояния оказывается самым удобным и разумным выходом

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

Конструкторы (зачем)
Конструктор, атрибут доступа которого отличается от public, ограничивает возможности создания объектов данного класса.
Например, можно запретить программистам, работающим с вашим пакетом, расширять тот или иной класс, если сделать все конструкторы доступными лишь из пакета.
Кроме того, можно пометить ключевым словом protected те конструкторы, которые предназначены для использования исключительно в подклассах.

Конструкторы
Если не объявлять для класса никаких конструкторов, Java создает безаргументный конструктор по умолчанию, который не делает ничего.
Этот конструктор создается автоматически лишь в тех случаях, когда нет никаких других конструкторов и он инициализирует все поля нулями

Конструкторы
Если безаргументный конструктор должен существовать наряду с одним или несколькими конструкторами, использующими аргументы, можно явно определить его.
class SimpleClass {
/ * * Эквивалент конструктора по
умолчанию * /
public SimpleClass () {
….
}
}

Инициализаторы
Допустимой конструкцией в теле класса является объявление инициализаторов. Записываются объектные инициализаторы внутри фигурных скобок.
public class Test {
private int x, y, z;
// инициализатор объекта
{ x=3;
if (x>0) y=4;
z=Math.max(x, y);
}
}

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

Инициализаторы
Можно использовать статические инициализаторы
public class SmallSquares {
private static final int LIMIT = 10;
private static final int[] square = new
int[LIMIT];
static { for (int i = 0; i < LIMIT; i++) {
square[i] = i * i; }
}//блок статической инициализации

Инициализаторы
public static int getSquare(int i) {
return square[i];
}
public static void main(String[] args) {
System.out.println("3 squared is " +
getSquare(3));
}
}

Инициализаторы
При создании экземпляра класса вызванный конструктор выполняется следующим образом:
если первой строкой идет обращение к конструктору родительского класса (явное или добавленное компилятором по умолчанию), то этот конструктор исполняется;
в случае успешного исполнения вызываются все инициализаторы полей объекта в том порядке, в каком они объявлены в теле класса;

Инициализаторы
если первой строкой идет обращение к другому конструктору этого же класса, то он вызывается. Повторное выполнение инициализаторов не производится.

Инициализаторы
Второй пункт имеет ряд важных следствий.
Во-первых, из него следует, что в инициализаторах нельзя использовать переменные класса, если их объявление записано позже
Во-вторых, теперь можно сформулировать наиболее гибкий подход к инициализации final-полей.
Главное требование – чтобы такие поля были проинициализированы ровно один раз. Это можно обеспечить в следующих случаях:

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

страница 1
скачать
Другие похожие работы: