Как запретить наследование класса java
Наследование класса можно запретить, обозначив класс как final :
final class Parent > class Child extends Parent >
Этот код выдаст ошибку cannot inherit from final Parent
Наследование в Java: основные правила с примерами

Наследование в Java — механизм, который позволяет одному классу получить все элементы и свойства другого класса. Этот процесс также называют расширением, преобразованием или отношением «родитель-потомок».
Детям из Мариуполя нужно 120 ноутбуков для обучения — подари старое «железо», пусть оно работает на будущее Украины
Суперкласс (родитель) — основной класс, от которого принимаются все элементы.
Подкласс (расширенный, дочерний) — класс, который преобразовывается от другого класса, при этом может иметь свои элементы.
Зачем применяют наследование в Java? Суть в том, что можно образовать новые классы, используя уже имеющийся код. При этом есть возможность добавить другие переменные в дочерний класс, получив при этом новый.
Курс Python.
Цю мову програмування використовують від базових концепцій до складних застосувань у сферах штучного інтелекту. Після проходження курсу гарантовано отримай роботу в ІТ.
Синтаксис:
class Имя-подкласса extends Имя-суперкласса < // свойства и элементы >
Ключевое слово extends означает, что создается новый класс от уже имеющегося.
class Fruit < // поля и элементы >// применяем расширение class Apple extends Fruit < // свойства и элементы Fruit // свойства и элементы Apple >
Из примера видно, что класс Apple создается из Fruit, при этом наследуются все его элементы. Так, Fruit — это класс-родитель, а Apple — класс-потомок.
Как наследовать?
Основной и дочерний класcы создают определенную иерархию. На вершине — всегда базовый, а под ним строятся подклассы. При этом преобразованный класс служит родителем для других подклассов.
В Java существуют такие способы преобразования:
- одиночное;
- многоуровневое;
- иерархическое.
Рассмотрим их по порядку.
Курс Англійської.
Вивчай англійську прямо зі свого смартфона за допомоги смарт-платформи.
Одиночное наследование
Механизм одиночного наследования очень прост: подкласс получает свойства только от одного основного класса:
class Pet < public void walk ()class Cow extends Pet < public void moo () >
I will walk I will moo
Многоуровневое наследование
Многоуровневый процесс происходит при наследовании дополнительного класса от базового, затем этот же класс действует уже как основной для следующего:
class Pet < public void walk ()> class Cat extends Pet < public void sleep () > class Kitty extends Cat < public void purr () > class TestIn < public static void main(String args[])< Kitty c=new Kitty(); c.walk (); c.sleep(); c.purr(); >>
I will walk I will sleep I will purr
То есть, в конце мы обращаемся к методу walk() от Pet, потом к sleep() от Cat, а затем к purr () от Kitty.
Иерархическое наследование
Иерархическое наследование происходит, когда несколько подклассов получают разрешение от одного суперкласса:
class Pet < public void walk()< System.out.println ("I will walk");>> class Cat extends Pet < public void sleep ()< System.out.println("I will sleep");>> class Kitty extends Pet < public void purr()< System.out.println("I will purr");>> class TestIn < public static void main(String args[])< Kitty c=new Kitty(); c.purr(); c.walk(); //c.sleep -Error >>
I will purr I will walk
Класс Kitty унаследовал от Pet walk(), а также у него есть свой purr (), соответственно метод sleep() от Cat ему не доступен.
Правила наследования
Написание кода подчиняется своим законам. В Java также есть определенные правила.
Обращение к методу родителя с помощью super
Чтобы обратиться к методу родителя, нужно использовать ключевое слово super.
Курс Комерційний директор.
Зосередження на практичних завданнях та послідовному аналізі проектів замість великої теорії. Реалізуй свої мрії про керівну посаду після завершення курсу.
Давайте используем один из предыдущих вариантов-примеров, добавив super в преобразованный Cow:
class Cow extends Pet < // обращаемся к walk в Pet super. walk (); System.out.println("I will produce milk");>public void moo () < System.out.println ("I will moo");>> class TestIn< public static void main (String args[])< Cow small=new Cow(); small.walk (); small. moo (); >>
I will walk I will produce milk I will moo
В главном Pet есть walk (), также и в расширенном Сow, но уже с приставкой super.walk (), мы обращаемся к walk () в суперкласс из подкласса.
Получение доступа к защищенным элементам и методам
Если protected (защищен) стоит перед элементами и методами — это указание на то, что к ним можно обратиться из производного класса:
class Pet < protected String name; protected void display () System.out.println (“I am a pretty pet”); >class Kitty extends Pet < public void getInfo ()< System.out.println (" Call me .." + name);>> class TestIn< public static void main (String args[])< Kitty small=new Kitty(); // обращаемся к защищенному display small.name = “Lilu”; small.display (); small.getInfo(); >>
I am a pretty pet Call me Lilu
Как видно из примера, у нас есть основной класс — Pet — с защищенными name и display. Чтобы обойти эту защиту, мы создали новый объект small подкласса Kitty и получили необходимый доступ.
Наследовать можно всего один класс
Интересно, что в Java нет многократного наследования — оно возможно только от одного суперкласса.
public class extends Pet, Сow, Cat <>
Важно! В Java класс не может унаследовать ничего сам от себя.
Наследуется все, кроме приватных переменных и методов
В Java модификатор private сообщает о том, что классы-наследники не получат от родителя элементы с таким обозначением. Если вы попробуете произвести extends, компилятор выдаст ошибку.
Как переделать метод класса-родителя
Override (переопределение) — мощный инструмент, который применяется, когда необходимо изменить или переопределить реализацию метода, полученного от суперкласса.
class Cow extends Pet
Важные моменты при использовании Override:
- переопределить можно только унаследованные методы;
- название и параметры метода в родителе и наследнике — одинаковые;
- методы с обозначением private не переопределяются.
Как запретить наследование
Запретить создание подкласса можно просто применив final. Если класс отмечен как final, то ни один другой класс не может унаследовать от него элементы .
final class Pet < >class Kitty extends Pet
В результате мы получим ошибку.
Pet обозначен как final, поэтому Kitty не может получить от него ни поля ни переменных .
Це хороший спосіб розвитку вашої кар’єри в IT-індустрії. Після проходження курсу Mate гарантує вам офер мрії.
Класс. Наследование. Запрет функции.
А как запретить, например, только функцию test(float i), а функцию test(BYTE i) оставить доступной?
22 ответа
05 октября 2009 года
1.2K / / 09.03.2007
Например так
class MyB : public MyA
private:
void test(float i)
MyA::test(i);
>
public:
void test(BYTE i)
MyA::test(i);
>
>;
06 октября 2009 года
29 / / 07.04.2008
Понятно, спасибо. Правда есть минус — если одинаковых ф-ий много, то переписывать придётся их все(
Ещё вопрос: Есть ли возможность запретить использование ф-ии (т.б. сказать компилятору, чтобы он в наследуемый класс не помещал такую-то ф-ию)? Мб директива есть для этого?
Примерно как-нибудь так:
class B : public A <
not_used A::test; // Что-то в таком роде (если такое возможно)
>;
06 октября 2009 года
4.8K / / 20.01.2000
Ещё вопрос: Есть ли возможность запретить использование ф-ии (т.б. сказать компилятору, чтобы он в наследуемый класс не помещал такую-то ф-ию)? Мб директива есть для этого?
А что значит «не помещал такую-то ф-ию в класс» ?
06 октября 2009 года
29 / / 07.04.2008
А что значит «не помещал такую-то ф-ию в класс» ?
В классе A ф-ия есть, а в классе B (наследуемого от класса А) небыло её (ф-ии) вообще.
06 октября 2009 года
1.2K / / 09.03.2007
В классе A ф-ия есть, а в классе B (наследуемого от класса А) небыло её (ф-ии) вообще.
А почему просто не ограничить к ней доступ посредством private?
06 октября 2009 года
2.7K / / 02.02.2008
Понятно, спасибо. Правда есть минус — если одинаковых ф-ий много, то переписывать придётся их все
Значит иерархия классов неправильная. Надо наследовать A и B от общего базового класса, в котором есть все необходимое обоим.
Можно сделать еще так:
struct A
void func1()<>
void func2()<>
void func3()<>
void func4()<>
>;
В принципе, при наследовании происходит примерно то же.
06 октября 2009 года
4.8K / / 20.01.2000
В классе A ф-ия есть, а в классе B (наследуемого от класса А) небыло её (ф-ии) вообще.
Реализация всегда наследуется полностью.
Можно ограничивать доступ. Можно реализовать примеси (стратегии), в т.ч. применив множественное наследование.
И все равно твой вопрос не понятен.
Что значит «не было вообще»?
Какая разница между «нет вообще» и «запрещена» (оба определения в нотации автора топика) ?
В каком контексте (для чего) задан вопрос?
08 октября 2009 года
1.1K / / 01.08.2005
Значит иерархия классов неправильная.
Тем не мение такие грабли встречаются. К примеру в Java есть возможность создать неизменяемую колекцыю данных с оригинальной. По сути создается оболочка над изначальной келекцыей в которой метод add не делегирует действие агрегату а генерирует есключение.
Кстати сопутствующий вопрос (С++ давно забыл) как при таком припрятывании метода розруливается приведение к родительскому типу ? Ибо во многих языках такой фокус невозможен и для скрытия метода приходится создавать новый интерфейс что тоже не всегда удобно.
08 октября 2009 года
1.2K / / 09.03.2007
Кстати сопутствующий вопрос (С++ давно забыл) как при таком припрятывании метода розруливается приведение к родительскому типу ? Ибо во многих языках такой фокус невозможен и для скрытия метода приходится создавать новый интерфейс что тоже не всегда удобно.
По большому счету никак. Если класс привести к базовому, метод все равно можно будет вызвать.
08 октября 2009 года
2.7K / / 02.02.2008
Rebbit, пока попытаюсь поэкспериментировать. Мои компиляторы (gcc, и тот, что в Экспресс Студии) не ругаются на такое:
int main()
MyA* aPtr = new MyB();
aPtr->test(20);
aPtr->test(20.1);
delete aPtr;
return 0;
>
если virtual убрать, то не будет методы MyB вызывать вообще. Вот и обманули запрет 🙂
08 октября 2009 года
1.2K / / 09.03.2007
Вот и обманули запрет 🙂
Помнится у Саттера в книжке такая глава была: как «нелегально» получить доступ к закрытым членам 🙂
08 октября 2009 года
2.7K / / 02.02.2008
Можно еще защищенное наследование использовать. Но это вообще будет близкий аналог агрегирования, которое я привел в первом ответе.
10 октября 2009 года
19 / / 14.09.2009
Kogrom
Ничего ты не обманул: virtual значит, что функции должны быть переопределены в наследнике. Когда ты убираешь слово «virtual» ты снимашь это требование.
10 октября 2009 года
4.8K / / 20.01.2000
Kogrom
Ничего ты не обманул: virtual значит, что функции должны быть переопределены в наследнике. Когда ты убираешь слово «virtual» ты снимашь это требование.
Никто никому ничего не должен. virtual ничего не требует, он лишь «включает» механизм полиморфности. Виртуальный метод родительского класса не обязательно должен быть переопределен.
10 октября 2009 года
265 / / 16.12.2006
Kogrom
Когда ты убираешь слово «virtual» ты снимашь это требование.
Вы не правы. Функция, которая объявлена как виртуальная в базовом классе будет виртуальной в любом наследнике независимо от того, указано ли ключевое слово virtual в наследнике в объявлении функции.
Ключевое слово virtual в наследнике в этом случае используется ( или не используется:) ) только для повышения читабельности.
10 октября 2009 года
19 / / 14.09.2009
Никто никому ничего не должен. virtual ничего не требует, он лишь «включает» механизм полиморфности. Виртуальный метод родительского класса не обязательно должен быть переопределен.
Я не говорил слова «должен». Я говорил слово «значит». Остальное твои фантазии.
Виртуальная функция может быть переопределена в наследнике, иначе она будет та же.
Вы не правы. Функция, которая объявлена как виртуальная в базовом классе будет виртуальной в любом наследнике независимо от того, указано ли ключевое слово virtual в наследнике в объявлении функции.
Ключевое слово virtual в наследнике в этом случае используется ( или не используется:) ) только для повышения читабельности.
Прочитай ещё раз и скажи где я говорил про ключевое слово virtual в наследнике ?
Не называй меня на «вы». Я буду обращптся к тебе как угодно.
10 октября 2009 года
1.2K / / 09.03.2007
Не называй меня на «вы». Я буду обращптся к тебе как угодно.
[QUOTE=Airhand;]
Kogrom
Ничего ты не обманул: virtual значит, что функции должны быть переопределены в наследнике. Когда ты убираешь слово «virtual» ты снимашь это требование.
[/QUOTE]
К чему этот ответ? Как уже заметил Green (а вы это проигнорировали, тупо придравшись к словам), virtual отнюдь не выставляет подобных требований.
[QUOTE=Airhand;]
Виртуальная функция может быть переопределена в наследнике, иначе она будет та же.
[/QUOTE]
Сами себе противоречите 😉
10 октября 2009 года
4.1K / / 05.01.2007
Kogrom
Ничего ты не обманул: virtual значит, что функции должны быть переопределены в наследнике. Когда ты убираешь слово «virtual» ты снимашь это требование.
мне кажется или чувак путает virtual с abstract?
10 октября 2009 года
4.8K / / 20.01.2000
Я не говорил слова «должен». Я говорил слово «значит». Остальное твои фантазии.
Виртуальная функция может быть переопределена в наследнике, иначе она будет та же.
Что-то с памятью или руки пишут не то что голова думает?
Перепрочти СВОЙ пост внимательно:
Ничего ты не обманул: virtual значит, что функции должны быть переопределены в наследнике. Когда ты убираешь слово «virtual» ты снимашь это требование.
10 октября 2009 года
19 / / 14.09.2009
Green
Да я сказал «должны». Я ошибся, на самом деле «может».
Почему, я же сказал, что буду обращаться к вам как вам будет угодно. А ко мне не надо обращаться на «вы».
К чему этот ответ? Как уже заметил Green (а вы это проигнорировали, тупо придравшись к словам), virtual отнюдь не выставляет подобных требований.
Вы хоть поняли, ЧТО написали ? Наследный класс это тот же базовый, которому добавили свойства и методы. Поэтому функция, определённая в базовом классе, будет и в наследном. Это легко проверить: выведете в функции что-нибудь на экран, а потом вызовите наследный класс. Только убедитесь, что функция в базовом классе вызывается в базовом классе.
10 октября 2009 года
2.7K / / 02.02.2008
Kogrom
Ничего ты не обманул: virtual значит, что функции должны быть переопределены в наследнике. Когда ты убираешь слово «virtual» ты снимашь это требование.
Наверное, я не четко выразился. Обманули не с помощью virtual. Он тут к слову пришелся. «Обманули» компилятор сославшись на дочерний класс, использовав указатель родительского. Причем в случае с virtual так можно обратиться к закрытым методам дочернего класса. Без virtual обращаемся к методам родительского класса, которые хотели запретить.
Я объясняю эту особенность так (вполне возможно, что вру): всякие слова для запрета (ограничения) доступа используются для того, чтобы компилятор не пропустил ошибочный код, чтобы не дал сослаться на закрытый метод вне класса. Но использовав указатель на родительский класс, мы «закрываем глаза» компилятору.
После компиляции в объекте остаются одинаковые указатели на функции класса хоть для открытых методов, хоть для закрытых. Ну и при использовании virtual по vtable можно вырулить на то, что должно было быть недоступным.
Где-то еще надо было важно сказать про срезку, но я не придумал где.
11 октября 2009 года
4.8K / / 20.01.2000
Вы хоть поняли, ЧТО написали ? Наследный класс это тот же базовый, которому добавили свойства и методы. Поэтому функция, определённая в базовом классе, будет и в наследном. Это легко проверить: выведете в функции что-нибудь на экран, а потом вызовите наследный класс. Только убедитесь, что функция в базовом классе вызывается в базовом классе.
Ты сам то понял, что написал?
Уже утомляет этот детский непрофессиональный лепет.
Прочитай хотя бы одну книгу по ООП, чтоб понять что такое наследование, какие виды наследования бывают, что именно наследуется при разных видах наследования.
У тебя проблемы как с пониманием предмета, так и с терминологией (в каждом предложении!).
P.S. Советую хорошенько задуматься над идеей почитать литературу прежде, чем опять начать нести ерунду или хамить.
Запрет наследования: изолированные классы
Создавая отношения базовых классов и подклассов, вы получаете возможность использовать поведение существующих типов. Но что делать, когда нужно определить класс, не позволяющий получение подклассов? Например, предположим, что в наше пространство имен добавлен еще один класс, расширяющий уже существующий тип SalesPerson. На рис. 4.8 показана соответствующая схема.

Рис. 4.8. Расширенная иерархия служащих
Класс PTSalesPerson является классом, представляющим продавца, работающего на неполную ставку, и предположим, например, что вы хотите, чтобы никакой другой разработчик не мог создавать подклассы из PTSalesPerson. (В конце концов, какую еще неполную ставку можно получить на основе неполной ставки?) Чтобы не допустить возможности расширения класса, используйте ключевое слово C# sealed.
// Класс PTSalesPerson не сможет быть базовым классом.
public sealed class PTSalesPerson: SalesPerson
public PTSalesPerson(string fullName, int age, int empID, float currPay, string ssn, int numbOfSales): base (fullName, age, empID, currPay, ssn, numbOfSales)
// Логика конструктора…
// Другие члены…
Поскольку класс PTSalesPerson изолирован, он не может служить базовым Классам никакому другому типу. Поэтому при попытке расширить PTSalesPersоn вы получите сообщение об ошибке компиляции.
// Ошибка компиляции!
public class ReallyPTSalesPerson: PTSalesPerson
Наиболее полезным ключевое слово sealed оказывается при создании автономных классов утилит. Класс String, определённый в пространстве имен Sуstem, например, явно изолирован.
public sealed class string: object, IComparable, ICloneable, IConvertible, IEnumerable
Поэтому вы не сможете создать новый класс, производный от System.String:
// Снова ошибка!
public class MyString: string
Если вы хотите создать новый класс, использующий функциональные возможности изолированного класса, единственным вариантом будет отказ от классического наследования и использование модели локализации/делегирования (известной еще как отношение локализации, «has-a»).
Читайте также
8.17.6 Изолированные маршруты BGP
8.17.6 Изолированные маршруты BGP Маршрут исключается, если:? Он присутствует в списке изолированных маршрутов из сообщения об изменениях.? В изменениях приведен заменяющий маршрут.? Система BGP завершает такое соединение. Все маршруты через эту систему становятся
Проблема наследования
Проблема наследования Если существует необходимость наследовать от класса Singleton, то следует придерживаться определенных правил.Во-первых, класс-наследник должен переопределить метод Instance(), так, чтобы создавать экземпляр производного класса. Если не предполагается, что
Глава 8. Изучение наследования
Глава 8. Изучение наследования НаследованиеНаследованием (inheritance) называется такое отношение между классами, когда один класс использует часть структуры и/или поведения другого или нескольких классов. При наследовании создается иерархия абстракций, в которой подкласс
Правило 39: Продумывайте подход к использованию закрытого наследования
Правило 39: Продумывайте подход к использованию закрытого наследования В правиле 32 показано, что C++ рассматривает открытое наследование как отношение типа «является». В частности, говорится, что компиляторы, столкнувшись с иерархией, где класс Student открыто наследует
Правило 40: Продумывайте подход к использованию множественного наследования
Правило 40: Продумывайте подход к использованию множественного наследования Когда речь заходит о множественном наследовании (multiple inheritance – MI), сообщество разработчиков на C++ разделяется на два больших лагеря. Одни полагают, что раз одиночное исследование (SI) – это хорошо,
Второй принцип: поддержка наследования в C#
Второй принцип: поддержка наследования в C# Теперь, после исследования различных подходов, позволяющих создавать классы с хорошей инкапсуляцией, пришло время заняться построением семейств связанных классов. Как уже упоминалось, наследование является принципом ООП,
Цепочка наследования типа Page
Цепочка наследования типа Page Как вы только что убедились, готовый генерируемый класс, представляющий файл *.aspx, получается из System.Web.UI.Page. Подобно любому базовому классу, этот тип обеспечивает полиморфный интерфейс всем производным типам. Однако тип Page является не
18.6. Пример множественного виртуального наследования A
18.6. Пример множественного виртуального наследования A Мы продемонстрируем определение и использование множественного виртуального наследования, реализовав иерархию шаблонов классов Array (см. раздел 2.4) на основе шаблона Array (см. главу 16), модифицированного так, чтобы он
19. Применение наследования в C++
19. Применение наследования в C++ При использовании наследования указатель или ссылка на тип базового класса способен адресовать объект любого производного от него класса. Возможность манипулировать такими указателями или ссылками независимо от фактического типа
2.2.4. Типы сущностей и иерархия наследования
2.2.4. Типы сущностей и иерархия наследования Как было указано выше, связи определяют, является ли сущность независимой или зависимой. Различают несколько типов зависимых сущностей.Характеристическая — зависимая дочерняя сущность, которая связана только с одной
Просмотр дерева наследования классов
Просмотр дерева наследования классов ClassView предоставляет очень интересную и полезную возможность просмотра дерева наследования классов приложения. Для этого выберите название интересующего вас класса из списка классов и откройте временное меню, нажав правую кнопку
Смысл наследования
Смысл наследования Мы уже рассмотрели основные способы наследования. Многое еще предстоит изучить, в частности, множественное наследование и детали того, что происходит с утверждениями в контексте наследования (понятие субконтрактов).Но вначале следует поразмышлять
Отложенные классы как частичные интерпретации: классы поведения
Отложенные классы как частичные интерпретации: классы поведения Не все отложенные классы так близки к АТД как STACK. В промежутке между полностью абстрактным классом, таким как STACK, в котором все существенные компоненты отложены, и эффективным классом, таким как FIXED_STACK,
Примеры множественного наследования
Примеры множественного наследования Множественное наследование это, по сути, прямое приложение уже рассмотренных принципов наследования, — класс вправе иметь произвольное число родителей. Однако, изучая этот вопрос более внимательно, можно обнаружить две интересные
Лекция 16. Техника наследования
Лекция 16. Техника наследования Наследование — ключевая составляющая ОО-подхода к повторному использованию и расширяемости. В этой лекции нам предстоит исследовать новые возможности, разнородные, но демонстрирующие замечательные следствия красоты базисных идей.
Глобальная структура наследования
Глобальная структура наследования Ранее мы уже ссылались на универсальные (universal) классы GENERAL и ANY, а также на безобъектный (objectless) класс NONE. Пришло время пояснить их роль и представить глобальную структуру