
техпрог / Comp-Sci-07
.pdf
Материалы к лекции 7
Объектно-ориентированное программирование
Наследование
Из Википедии:
Наследование — один из четырѐх важнейших механизмов объектноориентированного программирования (наряду с инкапсуляцией, полиморфизмом и абстракцией), позволяющий описать новый класс на основе уже существующего (родительского), при этом свойства и функциональность родительского класса заимствуются новым классом.
Другими словами, класс-наследник реализует спецификацию уже существующего класса (базовый класс). Это позволяет обращаться с объектами класса-наследника точно так же, как с объектами базового класса.
Класс, от которого произошло наследование, называется базовым или родительским (англ. base class). Классы, которые произошли от базового, называются потомками,
наследниками или производными классами (англ. derived class).
Наследование в C++:
class A{ |
//базовый класс |
|
}; |
|
|
class B : public A{ |
//public наследование |
|
} |
|
|
class C : protected A{ |
//protected наследование |
|
} |
|
|
class Z : private A{ |
//private наследование |
|
} |
|
|
Наследование с public (class derived : public base). Все открытые |
||
(public) |
члены базового класса остаются открытыми и в производном. Закрытые |
(private) члены базового класса в производном классе недоступны.
Пример.
#include <iostream> using namespace std;
class base { int x;
public:
void setx(int n) { x = n; }
void showx() { cout << x << '\n'; }
};
// Класс наследуется как открытый
class derived : public base { int y;
public:
void sety(int n) { y = n; }
void showy() { cout << y << '\n'; }
// void showxy(){cout<<x<<y;} – так нельзя

void showxy(){showx();cout<<y;} };
int main()
{derived ob;
ob.setx(10); // доступ к члену базового класса ob.sety(20); // доступ к члену производного класса ob.showx(); // доступ к члену базового класса ob.showy(); // доступ к члену производного класса return 0;
}
Наследование с private - (class derived : private base). Все, включая открытые, члены базового класса становятся закрытыми (private) в производном классе и, следовательно, недоступны вне его.
Пример.
#include <iostream> using namespace std; class base {
int x; public:
void setx(int n) { x = n; }
void showx() { cout << x << '\n'; }
};
class derived : private base { int y;
public:
void sety(int n) { y = n; }
void showy() { cout << y << '\n'; }
};
int main()
{derived ob;
ob.setx(10); // ОШИБКА - теперь закрыто для производного класса ob.sety(20); // правильный доступ к члену производного класса ob.showx(); // ОШИБКА - теперь закрыто для производного класса ob.showy(); // правильный доступ к члену производного класса
return 0;
}
Тот же пример, но уже без ошибок.
#include <iostream> using namespace std; class base {
int x; public:
void setx(int n) { x = n; }
void showx() { cout << x << '\n'; }
};
class derived : private base { int y;
public:
//метод setx() доступен внутри класса derived void setxy(int n, int m) { setx(n); y = m; }
//метод showx() доступна внутри класса derived void showxy() { showx(); cout << y << '\n'; }
};
int main()
{derived ob; ob.setxy(10, 20); ob.showxy();

return 0;
}
Спецификатор доступа protected
Спецификатор доступа protected действует как private, но защищенные (protected) члены базового класса доступны для членов всех производных классов этого класса. Когда базовый класс наследуется производным классом как открытый (public), защищенный (protected) член базового класса остается защищенным (protected) членом производного класса (т. е. снова protected). Когда базовый класс наследуется как закрытый (private), то защищенный (protected) член базового класса становится закрытым (private) членом производного класса. Базовый класс может наследоваться с доступом protected. В этом случае открытые (public) и защищенные (protected) члены базового класса становятся защищенными (protected) членами производного класса, а закрытые (private) так и остаются закрытыми.
Пример.
#include <iostream> using namespace std; class base {
protected: // закрытые члены класса base, int a,b;
public:
void setab(int n, int m) { a = n; b = m; }
};
class derived : public base { int c;
public:
void setc(int n) { c = n; }
// эта функция имеет доступ к переменным a и b класса base void showabc() { cout << a << ' ' << b << ' ' << c << '\n';
}
};
int main()
{ derived ob; /* Переменные a и b здесь недоступны, поскольку являются закрытыми членами классов base и derived */
ob.setab(1, 2); /* если заменим при наследовании public на protected, то setab() будет недоступна */
ob.setc(3);
ob.showabc(); return 0;
}