2015-03-19 5 views
2

я вроде новичок в C# и изучения о запечатанном классе, когда я наткнулся этоможет реализация производного класса коррумпированного базового класса

«запечатанного класса в основном используется в целях безопасности путем предотвращения непреднамеренной вывод, по которому производный класс может испортить реализацию, предусмотренную в базовом классе '

Действительно ли это возможно? может ли производный класс действительно коррумпировать реализацию базового класса? Если так, пожалуйста, объясните пример.

+4

Это зависит от значения слова «коррумпированный» и дизайна базового класса. Но, например, если у вас есть тип, который должен быть неизменным, но не запечатан, тогда любой может создать из него модифицируемый класс - даже если состояние в базовом классе остается неизменным, разработчики не смогут полагаться на сам класс, являющийся неизменным. –

ответ

1

Say вам нужны ворота хранители:

public interface IGateKeeper 
{ 
    /// <summary> 
    /// Check if the given id is allowed to enter. 
    /// </summary> 
    /// <param name="id">id to check.</param> 
    /// <param name="age">age to check</param> 
    /// <returns>A value indicating whether the id is allowed to enter.</returns> 
    bool CanEnter(string id, int age); 

    ... other deep needs ... 
} 

Возможно, у вас есть прочная реализация, чтобы проверить большинство у входа в ваш бар:

public class MajorityGateKeeper : IGateKeeper 
{ 
    public virtual bool CanEnter(string id, int age) 
    { 
     return age >= 18; 
    } 

    ... other deep implementation ... 
} 

А также реализацию для VIP-зал:

public class VipGateKeeper : MajorityGateKeeper 
{ 
    public override bool CanEnter(string id, int age) 
    { 
     // Do the majotity test and check if the id is VIP. 
     return base.CanEnter(id, age) && (id == "Chuck Norris"); 
    } 
} 

И разорвать его в второй:

public class DrunkGateKeeper : VipGateKeeper 
{ 
    public override bool CanEnter(string id, int age) 
    { 
     return true; 
    } 
} 

DrunkGateKeeper является VipGateKeeper, так что вы можете скрыть его пьяным (приведение к VipGateKeeper) , Но это ужасная работа.

var gk = (VipGateKeeper) new DrunkGateKeeper(); 
var canEnter = gk.CanEnter("Miley Cyrus", 16);  // true (sic) 

Если вы сделаете VipGateKeeper запечатаны вы уверены, что она не может быть пьян: объект типа VipGateKeeper является VipGateKeeper больше ничего.

+0

OMG, вы о своем примере с образцом? –

+0

Я никогда не буду пытаться запретить ЕГО войти. – Orace

+0

@Orace, что бы вы пытались сказать, объект, когда он помечен как запечатанный, никак не может быть изменен, там он предотвращает любые изменения в реализации, предоставляемые в базовом классе, поскольку он не может быть унаследован? – Arun

0

Вы можете испортить реализацию базового класса из-за полиморфизма.

Если класс A имеет virtual метод, который может быть переопределение (т.е. полиморфный) и класс B перекрывает весь метод, а B не выводит один и тот же материал, как A «s реализация, то, похоже, B изменил фактическое поведение реализации A.

sealed на уровне уровня класса (f.e. override sealed) предназначен для избежания наследования и полиморфизма для всего класса.

Вы также можете предотвратить полиморфизм (наследование по-прежнему возможно) на некоторых членов перекрывая их в производном классе и пометив их с sealed модификатором:

public class A 
{ 
    public virtual void DoStuff() {} 
} 

public class B 
{ 
    public override sealed void DoStuff() {} 
} 
+0

Я не знал, что вы можете запечатать только определенного члена! Благодаря ! – Orace

+0

@Orace Добро пожаловать! В C# есть много «скрытых драгоценных камней»: D –

0

считают, что вы определили и внедрили метод в классе, в вашей программе вам нужна только эта реализация. например, вы возвращаете сообщение пользователю, всякий раз, когда вы вызываете этот метод, вы ожидаете возвращения определенного сообщения, считайте, что у вас есть дочерний класс, который переопределяет этот метод и показывает другое сообщение, когда вы вызываете этот метод, у вас есть другой результат, который не ожидается , если вы отмечаете класс как запечатанный, вы предотвращаете случайное наследование. запечатанная лицевая сторона монеты дизайна от абстрактного. когда вы определяете абстрактный класс, вы позволяете классам извлекать из него и реализовывать свои собственные реализации для методов, но закрытый класс не позволяет другим выводить его вообще.