using System; namespace ConsoleApplication1 { class Base { private int i = 5; private void Foo() { Console.WriteLine("Hello from private Foo()"); } public static void Main() { Derived d = new Derived(); d.i += 8; d.Foo(); Console.WriteLine("d.i = {0}", d.i); Console.ReadLine(); } } class Derived : Base { } }По правилам, прямой доступ к членам класса, объявленным с модификатором private, возможен только из этого же класса. Если необходим доступ к таким членам из производного класса, для этого имеется модификатор protected. Но пример компилируется и работает без единой ошибки! Я этого не могу объяснить. А вы?
Интересный примерИнкапсуляция и наследование в C#
#1
Отправлено 14.05.2007, 10:16:53
#5
Отправлено 14.05.2007, 16:30:32
мэйн и фу члены одного класса басе, который скрывает фу от внешнего мира и публикует мэйн.
член члена внутре должен хорошо видеть, вроде.
что касается приватности мэйн, то вероятно там управление кидается класс, который я не знаю, может быть басе, который внутри себя мэйн-то может разглядеть.
#8
Отправлено 15.05.2007, 09:32:49
Объявление main-функции - дело музыканта на СиДиезе, т.к. точных требований к определению в документации нет.Кстати, если Main() сделать тоже private, программа все равно компилируется и работает без ошибок!
Непонятно, зачем во всех книгах Main() всегда явно объявляют public...
#11
Отправлено 17.05.2007, 23:27:29
Попробуй в Derived класс добавить к метод, в котором будешь вызывать приватный метод предка или обращаться к приватному полю, тогда должно ругнуться.
По правилам, прямой доступ к членам класса, объявленным с модификатором private, возможен только из этого же класса. Если необходим доступ к таким членам из производного класса, для этого имеется модификатор protected.
Сообщение отредактировал Sham: 17.05.2007, 23:36:20
#12
Отправлено 18.05.2007, 01:33:53
В данном примере есть обращение из переменной производного класса к приватным полям и методам класса-предка. Его трудно не заметить - см. код примера.Пример компилируется, так как в классе Derived нет обращения к приватным полям и методам предка.
Обращение к приватным полям и методам, определенным в базовом классе, будет успешным даже из переменной производного класса, при условии, что оно выполняется в пределах кода базового класса. Причина успешной компиляции примера именно в этом.
#13
Отправлено 18.05.2007, 13:49:35
См.
Попробуй в Derived класс добавить к метод, в котором будешь вызывать приватный метод предка или обращаться к приватному полю, тогда должно ругнуться.
#15
Отправлено 18.05.2007, 14:27:39
Такого понятия даже нету - обращение может быть из метода, а не из переменной. Происходит обращение из метода Base.Main к приватной переменной Base.i, поэтому никак не возьму в толк где ты углядел криминал.В данном примере есть обращение из переменной производного класса к ...
#17
Отправлено 18.05.2007, 15:58:54
Расскажи, что курил перед тем, как заявить такое?Такого понятия даже нету - обращение может быть из метода, а не из переменной.
Не из метода Base.Main, а из объектной переменной, имя которой должно быть обязательно указано перед именем вызываемого метода или именем поля, к которому происходит обращение (поскольку они не объявлены как static). В данном примере эта объектная переменная имеет тип класса-наследника.Происходит обращение из метода Base.Main к приватной переменной Base.i,
Нет никакого криминала, все законно. Я просто привел интересный (на мой взгляд) пример. Он интересен тем, что атрибут private как у метода, так и у поля в базовом классе в данном случае не влияет на их доступность из переменной производного класса.поэтому никак не возьму в толк где ты углядел криминал.
#18
Отправлено 18.05.2007, 23:01:15
Вижуал, по-моему всё написано куда уж более ясно и точно. Если у тебя некое своеобразное представление о разграничениях доступа, то это имхо твои личные проблемы и к ООП языкам они отношения не имеют.Расскажи, что курил перед тем, как заявить такое?
Такого понятия даже нету - обращение может быть из метода, а не из переменной.
Либо ты всё шиворот на выворот перепутал, либо читай выше.Не из метода Base.Main, а из объектной переменной, имя которой должно быть обязательно указано перед именем вызываемого метода или именем поля, к которому происходит обращение
Происходит обращение из метода Base.Main к приватной переменной Base.i,
Имхо тебя смутил всего лишь тот факт, что в шарпе апкаст Derivet->Base происходит неявно, без необходимости писать static_cast<Base>(d). Других сложностей для понимания в упор не вижу.Нет никакого криминала, все законно. Я просто привел интересный (на мой взгляд) пример. Он интересен тем, что атрибут private как у метода, так и у поля в базовом классе в данном случае не влияет на их доступность из переменной производного класса.
поэтому никак не возьму в толк где ты углядел криминал.
#19
Отправлено 19.05.2007, 01:01:41
У меня "своеобразное представление" и "личные проблемы"? Хм, вроде бы раньше не было такого в твоей манере - переходить на личности. По теме: состояние класса должно быть надежно защищено - надеюсь, не станешь с этим спорить? А как это обеспечить? Сделать класс изолированным (sealed)? Это работает, но изолированные классы не всегда удобны в использовании (производные типы нужны довольно часто, да и что это за ООП без наследования). Изолированным класс следует делать только если заранее известно, что он не предназначен для наследования. Это трудно предсказать - и поэтому не зря компилятор C# делает любой класс по умолчанию неизолированным.Вижуал, по-моему всё написано куда уж более ясно и точно. Если у тебя некое своеобразное представление о разграничениях доступа, то это имхо твои личные проблемы и к ООП языкам они отношения не имеют.
Поля данных класса всегда следует объявлять private - элементарное правило, думаю, никто не станет с этим спорить. Но, как видно из приведенного примера, это тоже не всегда помогает. Я показал одну из таких скрытых опасностей - дальше можете поступать по своему усмотрению:
а) пользоваться этим в своей практической работе (рекомендую);
б) говорить про меня все, что угодно (что у меня "личные проблемы с пониманием языков ООП" и т.д.).
Количество пользователей, читающих эту тему: 1
пользователей: 0, неизвестных прохожих: 1, скрытых пользователей: 0