Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
lec4.doc
Скачиваний:
0
Добавлен:
01.05.2025
Размер:
159.23 Кб
Скачать

Наследование. Производные классы.

1) Производный класс, наследование полей и методов и добавление новых полей и методов на С++

Имеем класс Record (min,sec), введем новый класс Sprint, учитывающий десятые доли секунды спортсмена, спринтерский бег. (int dec) . В классе добавим метод Putdec , устанавливающий количество десятых долей и Numberdec, вычисляющий общее число десятых долей секунды у объектов (например, для сравнения результатов).

class Record

{

public:

void Init (int m,int s); // задание значений полей

int Numbersec();

private:

int min;

int sec;

};

int Record::Numbersec()

{

return min*60+sec;

}

void Record::Init(int m,int s)

{

min=m;

sec=s;

}

// наследуемый класс

class Sprint : public Record // Sprint-наследник Record

{

public:

// новые методы Sprint

Void Putdec(int d);

Int Numberdec();

private:

// новое поле Sprint

int dec;

};

В класссе Sprint имеются также public методы Numbersec, Init и private поля min, sec.

void Sprint::Putdec(int d)

{

dec=d;

}

int Sprint::Numberdec()

{

int k;

k=Numbersec();

return k*10+dec;

}

int main(int argc, char* argv[])

{

int m,n;

Record x,y;

x.Init(4,36); // min=4 sec=36

y.Init(2,4); // min=2 sec=4

Sprint z;

z.Init(1,8); // min=1 sec=8

z.Putdec(4); // dec=4

m=z.Numberdec(); // m=684

n=z.Nubersec(); // n=68 вызов наследуемого метода

}

2) Модификатор доступа protected

Заменим вызов Numbersec() из Numberdec прямым вычислением:

Int Sprint::Numberdec()

{

int k;

k=min*60+sec; // вместо k=Numbersec();

return k*10+dec;

}

Ошибка! min, sec is not accessible

min , sec определены как private в Record и не могут вызываться из методов другого класса Sprint, даже после наследования.

Исправление:

class Record

{

public:

void Init (int m,int s);

int Numbersec();

protected: // вместо private:

int min;

int sec;

};

К полям и методам из protected могут обращаться как методы Record, так и методы всех наследуемых классов, (Sprint).

class A

{

......

protected:

int x;

....

};

......

class B : public A

{

....

}

class C : public B

{

....

};

Идентификатор x может появиться в любом методе классов A, B, C.

Инкапсуляция: public, private, protected разграничивают доступ к полям и методам.

3) Модификатор в заголовке наследуемого класса

class Sprint : public Record // public - открытое наследование

public означает, что наследуемые поля из Record остаются без изменения:

Record public -> Sprint public

Record protected -> Sprint protected

Record private -> Sprint private

Другие варианты:

class Sprint : protected Record // защищенное наследование

Наследуемые поля и методы перестают быть public

Record public -> Sprint protected

Record protected -> Sprint protected

Record private -> Sprint private

class Sprint : private Record // закрытое наследование

Все наследуемые поля и методы становятся private

Record public -> Sprint private

Record protected -> Sprint private

Record private -> Sprint private

Int main(int argc, char* argv[])

{

int m,n;

Record x;

x.Init(2,8); // правильно Init в Record public

Sprint z;

z.Init(1,8); // min=1 sec=8 // ошибка, Init теперь private

z.Putdec(4); // dec=4 // правильно Putdec определена в Sprint как public

m=z.Numberdec(); // m=684 // правильно

n=z.Nubersec(); // n=68 // ошибка

}

В современных ООП языках используется только открытое наследование

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

В C++ класс может быть наследником нескольких классов.

class Record

{

public:

..........

protected:

int min,sec;

...........

}

class Person

{

public:

..........

protected:

char Fam[30];

int Vozrast;

.............

}

class Sportsman : public Person , public Record

{

public:

..........

private:

int Category;

............

}

В классе Sportsman наследуются поля min, sec, Fam,Vozrast.

Пусть в классе Person имеется поле double min.

class Person

{

public:

..........

protected:

char Fam[30];

int Vozrast;

double min;

.............

}

void Sportsman::Putmin(int m)

{

min=m; // какое min из двух ??

......

}

Решение – указывать явно класс. Person::min=m;

В современных языках множественное наследование отсутствует !

5) Наследование на языке java

Наследуемый класс – подкласс (subclass), класс от которого наследуется – суперкласс (superclass).

Смысл prrotected такой же.

Вариант программы с дополнительным классом для задания main.

class Record // это суперкласс

{

protected int min,sec;

public void Init(int m,int s)

{

min=m;

sec=s;

}

public int Numbersec()

{

return min*60+sec;

}

}

class Sprint extends Record // extends наследует (расширяет) – это подкласс

{

private int dec;

public void Putdec(int d)

{

dec=d;

}

public int Numberdec()

{

int k;

k=min*60+sec;

return k*10+dec;

}

}

public class WorkSport // класс для main public!

{

public static void main (String args[] )

{

int p;

Record a=new Record(); // объект Record

a.Init(2, 40);

p=a.Numbersec();

System.out.printf("%d\n ", p);

Sprint b=new Sprint(); // объект Sprint

b.Init(1, 10); // вызов наследуемого метода; b.min=5; - ошибка!

b.Putdec(6);

p=b.Numberdec();

System.out.printf("%d\n ", p);

}

}

На консоли:

160

706

WorkSport содержит единственный метод main. Файл с тремя классами : WorkSport.java!!

Понятие пакета package в java

На C++ размещение файлов в интегрированных средах (не консольное приложение):

1. Record.h – заголовочный файл базового класса

class Record

{

public:

void Init (int m,int s);

int Numbersec();

protected: // вместо private:

int min;

int sec;

};

2. Record.cpp – файл с методами базового класса

int Record::Numbersec()

{

return min*60+sec;

}

void Record::Init(int m,int s)

{

min=m;

sec=s;

}

3. Sprint.h - Заголовочный файл производного класса

class Sprint : public Record // Sprint-наследник Record

{

public:

// новые методы Sprint

void Putdec(int d);

int Numberdec();

private:

// новое поле Sprint

int dec;

};

4. Sprint.cpp – файл с методами производного класса

void Sprint::Putdec(int d)

{

dec=d;

}

int Sprint::Numberdec()

{

int k;

k=Numbersec();

return k*10+dec;

}

5. lab4.cpp – основной файл с функцией main

int main(int argc, char* argv[])

{

int m,n;

Record x,y;

Sprint z;

.......

}

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

Пример создания пакета

Создание проекта: file – new – java project (lab4)

Создание пакета: file – new – Package (sports)

Создание отдельных 3 файлов-public классов

file - new – class

package sports;

public class Record

{

protected int min,sec;

public void Init(int m,int s)

{

min=m;

sec=s;

}

public int Numbersec()

{

return min*60+sec;

}

}

file - new – class

package sports;

public class Sprint extends Record

{

private int dec;

public void Putdec(int d)

{

dec=d;

}

public int Numberdec()

{

int k;

k=min*60+sec;

return k*10+dec;

}

}

file - newclass

package sports;

public class worksport

{

public static void main (String args[] )

{

int p;

Record a=new Record();

a.Init(2, 40);

p=a.Numbersec();

System.out.printf("%d\n ", p);

Sprint b=new Sprint();

b.Init(1, 10);

b.Putdec(6);

p=b.Numberdec();

System.out.printf("%d\n ", p);

}

}

Размещение:

lab4\\src\\sports\\

record.java sprint.java worksport.java

6) Перегрузка методов и явное указание класса вызываемого метода

Возможна перегрузка метода из базового класса в производном классе.

Пример – переопределение Init в Sprint

class Record

{

public:

void Init (int m,int s);

protected:

int min;

int sec;

};

void Record::Init(int m,int s)

{

min=m;

sec=s;

}

class Sprint : public Record

{

public:

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]