Зміна видимості елементів батьківського класу

Ми вже з вами навчилися наслідувати класи. Знаємо, що дочірні класи наслідують всі змінні та методи батьківського класу, якщо вони мають видимість або Але, бувають моменти, коли, якісь змінні чи методи батьківського класу потрібно дозволити або заборонити використовувати за межами дочірнього класу.

У випадках, якщо потрібно зробити одну дію зі всіма змінними та методами батьківського класу, то достатньо вказати відповідний тип наслідування. Але, якщо ми маємо це зробити лише з певною змінною чи методом, або зробити різні варіанти видимості, то використовувати відповідне наслідування не вийде.

В таких випадках можна використати ключове слово в середині дочірнього класу для змінної чи методу батьківського класу.

При цьому це потрібно вказувати в тій зоні видимості, яку ви хочете надати цій змінній чи методові.

На практиці це виглядатиме так:

    
            Тип_видимості:
            using ім’я_батьківського_класу::ім’я_змінної/методу;
        
    

При цьому зауважте, що навіть при методі ми не ставимо круглих дужок що метод класу це функція і там мали б бути дужки).


Давайте, розглянемо це на практиці:

    
            #include <iostream>

            class Father {
            private:
                //змінні та методи батьківського класу є приватними, тому
                //ми не будемо мати доступу до них в дочірніх класах
                int f_a = 7;

                void disA()
                {
                    std::cout << "private; " << f_a << std::endl;
                }

            protected:
                //змінні та методи батьківського класу є захищеними, тому
                //ми матимемо до них доступ в дочірньому класі але
                //не матимемо доступу за межами дочірнього класу
                int f_b = 17;

                void disB()
                {
                    std::cout << "protected; " << f_b << std::endl;
                }

            public:
                int f_c = 27;

                void disC()
                {
                    std::cout << "public; " << f_c << std::endl;
                }

            };

            class Child : public Father {
                //змінна "f_b" є захищеною в батьківському класі як і метод "disB()"
                //ми можемо до них звернутися в середині дочірнього класу.
                //але викликати їх за його межами не можна
                int c_b = f_b;

            public:
                //змінюємо видимість методів батьківського класу
                //на публічний тип видимості

                //оскільки метод "disA()" є приватним, то ми не можемо отримати до нього доступ
                //using Father::disA;

                //зауважте, що ми не ставимо "()" в кінці методів
                using Father::disB;

            private:
                //робимо метод "приватним" хоча він був публічним
                //тепер ми не зможемо його використати
                using Father::disC;

            };

            int main()
            {
                Child child;

                child.disB();

                //в батьківському класі ми мали метод "disC()", який був публічним
                //потім в дочірньому класі ми зробили його приватним, тому використання
                //за межами класу заборонене
                //child.disC();

                return 0;
            }
        
    

До речі, в старіших версіях С++ (11 і нижче) не вказують ключове слово


Також, ми вже знаємо, що батьківський та дочірній клас можуть мати однакові змінні та методи. І виклик таких методів виконується по принципу або, якщо ми вказуємо чітко з якого класу викликаємо дану змінну чи метод.

При цьому, якщо якийсь метод батьківського класу вам не потрібний в дочірньому, то ви можете його Для цього потрібно ініціалізувати його в дочірньому класі, а потім написати

        
            #include <iostream>

            class Father
            {
            public:
                void Dis()
                {
                    std::cout << "Father" << std::endl;
                }
            };

            class Child1 : public Father
            {
                //Видаляємо батьківський метод "Dis",
                //тому ми не можемо більше ним скористатися за межами
                //даного дочірнього класу
                void Dis() = delete;
            };

            class Child2 : public Father
            {

            };

            int main()
            {
                Child1 Child1;
                //метод "Dis" видалено, тому викликати його не можна
                //Child1.Dis();


                Child2 Child2;
                //в даному дочірньому класі метод "Dis" не видалено,
                //тому можемо його викликати
                Child2.Dis();

                return 0;
            }