Мы поможем в написании ваших работ!



ЗНАЕТЕ ЛИ ВЫ?

Управление доступом к классу.

Поиск

Управление доступом к классу осуществляется спецификатором класса.

Объявление класса

[спецификаторы] class ИмяКласса [extends суперкласс]
[implements список_интерфейсов]{

/*определение класса*/

}

 

Спецификатор Назначение

public класс доступен объектам своего пакета и вне его

не задан класс доступен только в своем пакете (friendly)

final класс не может иметь подклассов

abstract класс содержит абстрактные методы, объекты такого класса могут создавать только подклассы

Конструкторы классов

Конструктором называется метод, вызываемый для инициализации объекта при его создании.

Имя конструктора всегда совпадает с именем класса. Конструктор не может использовать оператор return и для него не указывается никакого типа возвращаемого значения. При объявлении конструктора можно указать модификаторы доступа public, protected или private.

Наличие явно описанного конструктора в классе не является обязательным. В этом случае при создании объекта используется конструктор по умолчанию. Такой конструктор не получает параметров и вызывает непосредственно конструктор суперкласса: super().

При этом, если суперкласс не имеет конструктора без списка параметров, то происходит ошибка компиляции.

Конструкторы не наследуются подклассами.

Тело конструктора заключается в фигурные скобки.

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

Конструктор может иметь следующее формальное описание:

ИмяКласса (СписокПараметров) {

ВызовКонструкторов

БлокОператоров

}

Вызов конструкторов выполняется операторами this и super с указанием в скобках списка параметров.

Например(Java):

public class C extends A {

public C() {this(1,20); }

// Вызов конструктора данного класса

public C(int i, int j) { }

}

Вызов конструкторов подчиняется следующим правилам:

- при создании объекта любого заданного класса будет неявно выполнена цепочка вызовов всех конструкторов его суперклассов;

- первым будет выполнено тело конструктора для Object;

- каждый последующий конструктор в цепочке будет выполняться только после выполнения конструктора своего непосредственного суперкласса;

- при создании объекта будут инициализированы все переменные экземпляра.

Наследование классов

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

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

Простое наследование

Класс, от которого произошло наследование, называется базовым или родительским (англ. base class). Классы, которые произошли от базового, называются потомками, наследниками или производными классами (англ. derived class).

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

Множественное наследование

При множественном наследовании у класса может быть более одного предка. В этом случае класс наследует методы всех предков. Достоинства такого подхода в большей гибкости. Множественное наследование реализовано в C++. Из других языков, предоставляющих эту возможность, можно отметить Python. Множественное наследование поддерживается в языке UML.

Множественное наследование – потенциальный источник ошибок, которые могут возникнуть из-за наличия одинаковых имен методов в предках. Практически всегда можно обойтись без использования данного механизма. Однако, если такая необходимость все-таки возникла, то, для разрешения конфликтов использования наследованных методов с одинаковыми именами, возможно, например, применить операцию расширения видимости - "::" - для вызова конкретного метода конкретного родителя.

Большинство современных объектно-ориентированных языков программирования поддерживает возможность одновременно наследоваться от класса-предка и реализовать методы нескольких интерфейсов одним классом. Этот механизм позволяет во многом заменить множественное наследование – методы интерфейсов необходимо переопределять явно, что исключает ошибки при наследовании функциональности одинаковых методов различных классов-предков. Пример наследования в Java: public class MyClass2 extends MyClass {…}

 

Перегрузка и переопределение членов класса

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

При переопределении метода использование модификаторов доступа должно удовлетворять следующим условиям:

если переопределяемый метод суперкласса не содержит ни одного из модификаторов доступа public, protected или private, то переопределяющий метод не должен иметь модификатора private.

если переопределяемый метод суперкласса имеет модификатор доступа protected, то переопределяющий метод должен иметь модификатор доступа public или protected.

если переопределяемый метод суперкласса имеет модификатор доступа public, то переопределяющий метод должен также иметь модификатор доступа public.

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

Если класс содержит переопределяющий метод, то переопределенный метод можно вызвать только с квалификацией ссылки ключевым словом super или именем суперкласса (для статических членов).

Пример переопределения методов в Java:

class A {

public void Metod1() { }

public static void Metod2() { }

}

class B extends A {

public Metod1() { }

...

Metod1(); // Вызов метода из класса B

super.Metod1(); // Вызов метода из класса A

A.Metod2();

}

Перегружаемыми методами называется группа методов с одинаковым именем, но различными списками параметров. Язык Java позволяет определять в классах перегружаемые методы.

Пример перегрузки метода myPrint:

public class MyClass2 {

 

private String str1; private void myPrint(int i){

System.out.println(i);

public MyClass2() { }

super(); private void myPrint(String s){

str1 = "String"; System.out.println(s);

myPrint(str1); }

myPrint(str1, 10); private void myPrint(String s, int i){

System.out.println(s);

} System.out.println(i);

}

}

 

Абстрактные классы

Абстрактный класс в объектно-ориентированном программировании — базовый класс, который не предполагает создания экземпляров. Абстрактный класс может содержать (и не содержать) абстрактные методы и свойства. Абстрактный метод не реализуется для класса, в котором описан, однако должен быть реализован для его неабстрактных потомков. Абстрактные классы представляют собой наиболее общие абстракции, то есть имеющие наибольший объем и наименьшее содержание.
В одних языках создавать экземпляры абстрактных классов запрещено, в других это допускается (например, Delphi), но обращение к абстрактному методу объекта этого класса в процессе выполнения программы приведёт к ошибке. Во многих языках допустимо объявить любой класс абстрактным, даже если в нём нет абстрактных методов (например, Java), именно для запрещения создания экземпляров. Абстрактный класс можно рассматривать в качестве интерфейса к семейству классов, порождённому им, но, в отличие от классического интерфейса, абстрактный класс может иметь определённые методы, а также свойства.
Абстрактные методы часто являются и виртуальными, в связи с чем понятия «абстрактный» и «виртуальный» иногда путают.

Массивы объектов

Допускается создание и инициализация статических и автоматических массивов из объектов класса. Синтаксически инициализация напоминает синтаксис для стандартных типов данных.

Point2D P1[3]={Point2D(2,4),Point2D(3,3),Point2D(4,6)};

Point2D P2[3]={Point2D(5),Point2D(4),Point2D(3)};

Point2D P3[3]={5,4,3};

Point2D P4[3]={Point2D(4),5,Point2D(3,1)};

На первый взгляд кажется, что для каждого элемента массива создается временный элемент типа Point2D, а потом массив инициализируется этим объектами, с помощью конструктора копий. На самом деле лишних действий нет. Вызываются лишь конструкторы для областей памяти, соответствующих элементов массива. Если у класса конструктор операции new [], можно создать массив в динамической области памяти. Инициализация такого массива не допустима.

Операция new гарантирует вызов конструктора для каждого объекта массива.Чтобы можно было описать массив объектов класса с конструктором, этот класс должен иметь стандартный конструктор, т.е. конструктор, вызываемый без параметров. Например, в соответствии с определением table tbl[10]; будет создан массив из 10 таблиц, каждая из которых инициализируется вызовом table::table(15), поскольку вызов table::table() будет происходить с фактическим параметром 15. В описании массива объектов не предусмотрено возможности указать параметры для конструктора. Если члены массива обязательно надо инициализировать разными значениями, то начинаются трюки с глобальными или статическими членами. Когда уничтожается массив, деструктор должен вызываться для каждого элемента массива. Для массивов, которые размещаются не с помощью new, это делается неявно. Однако для размещенных в свободной памяти массивов неявно вызывать деструктор нельзя, поскольку транслятор не отличит указатель на отдельный объект массива от указателя на начало массива, например:

void f()

{

table* t1 = new table;

table* t2 = new table[10];

delete t1; // удаляется одна таблица

delete t2; // неприятность:

// на самом деле удаляется 10 таблиц

}

В данном случае программист должен указать, что t2 - указатель на массив. Функция размещения хранит число элементов для каждого размещаемого массива. Требование использовать для удаления массивов только операцию delete[] освобождает функцию размещения от обязанности хранить счетчики числа элементов для каждого массива. Исполнение такой обязанности в реализациях С++ вызывало бы существенные потери времени и памяти и нарушило совместимость с С.



Поделиться:


Последнее изменение этой страницы: 2016-06-26; просмотров: 486; Нарушение авторского права страницы; Мы поможем в написании вашей работы!

infopedia.su Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав. Обратная связь - 3.12.74.189 (0.008 с.)