2010-05-17 3 views
1

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

Теперь класс B наследует A и класс C наследует B. Класс A имеет частный конструктор по умолчанию и защищенный параметризованный конструктор.

Я хочу, чтобы класс B, чтобы иметь возможность получить доступ ко всем защищенным функциям, определенным в классе А, но класс C может иметь доступ на некоторые из функций, только не все функции и класс C наследует класс B.

Как могу ли я ограничить доступ к некоторым функциям класса A из класса C?

EDIT:

namespace Db 
{ 
public class A 
    { 
    private A(){} 
    protected A(string con){assign this value} 

    protected DataTable getTable(){return Table;} 
    protected Sqlparameters setParameters(){return parameter;} 
    } 
} 

namespace Data 
{ 
public class B:A 
    { 
    protected B():base("constring"){} 

    protected DataTable output(){return getTable();} 
    protected sqlparameter values(param IDataParameter[] parameter){} 
    } 
} 

namespace Bsns 
{ 
public class C:B 
    { 
    protected C():base(){} 

    protected DataTable show() 
    {return values(setparameter());} 

    } 
} 

EDIT

Я думаю, что я пытаюсь сделать здесь множественное наследование.

Пожалуйста, проверьте.

class A 
{ 
//suppose 10 functions are declared 
} 

class B:A 
{ 
//5 functions declared which are using A's function in internal body 
} 


class C:B 
{ 
//using all functions of B but require only 4 functions of A to be accessible by C. 
} 
+0

Зачем вы хотите это сделать? Если класс C будет находиться в другой сборке от A и B, вы можете использовать защищенный внутренний. – 2010-05-17 05:08:16

+0

@Moron: Нет, все классы находятся в одной сборке. Любое другое решение, я могу разделить класс A на большее число классов, но не могу сделать это для B или C –

+0

@Moron: Что делать, если у меня есть все 3 класса в разных сборках, и я хочу, чтобы класс B получал доступ ко всем функциям, но класс C для доступа ограниченные функции. –

ответ

1

Я предлагаю вам переосмыслить свой дизайн. Может быть, есть более простой способ. Что, если C использует экземпляр B вместо того, чтобы извлекать из него (композицию)? Таким образом, C может использовать общественные методы B, но не получить доступ к защищенным.

Класс А не должен заботиться о уровне/глубине потомка. Если что-то отмечено защищенным, оно должно быть защищено как для B, так и для C (независимо от глубины цепочки наследования). B может выбрать ограничение своих потомков путем ужесточения ограничений (но это редко).

Если вы можете рассказать мне больше о вашем контексте - проблема, которую вы пытаетесь решить. Я могу дать вам более подробный/полезный ответ.

+0

@ Гишу: Я надеюсь, что приведенные выше детали могут стать полезными для понимания моей проблемы. Я тоже думал так же, как вы предлагали. Создание B запечатанного рейтера, чем наследуемого. –

+0

@ Гишу: Любые предложения, ожидающие ответа. –

+0

@Shantanu - Мне нужно знать, каковы реальные имена/обязанности A, B и C. Простое знание счетчика функций и модификаторов доступа не помогает. Вы можете повторно использовать наследование, а также состав/делегирование. Я склонен прибегать к наследованию только тогда, когда я на 100% уверен. – Gishu

2

Похоже, что вы, вероятно, должны использовать композицию, не наследуемую.

Класс A реализует calc() и разрешает().

Класс B имеет private A, но не является производным от А

класса C происходит от B и не имеет доступа к закрытому объекту в классе B.

+0

A используется B как базовый(), т.е. вызов конструктора наследования. –

4

Вы должны иметь классы A и B в той же сборке и классе C в другой сборке. Вы можете отметить участника, которому вы хотите ограничить доступ производными классами как protected internal. Это делает его членом, ну, защищенным и внутренним. Что касается ограничения доступа класса к классу C, достаточно отметить его internal. Так как это сделает его public в первой сборке, вы можете добавить protected для обеспечения инкапсуляции.

Выключает маркировку члена protected internal не делает его закрытым для занятий за пределами сборки. Похоже, что для всех целей и целей protected internal такой же, как и защищенный. К сожалению, единственный способ, которым я могу добиться этого, - отметить его внутреннее и смириться с тем, что участник является общедоступным для определяющей сборки.

Даже C# programming guide on MSDN получает это неправильно:

Объединив защищенные и внутренних ключевые слова, член класса может быть маркирован защищенным внутренним - только производных типами или типов в пределах одной и ту же сборки может получить доступ к этому члену ,

Фил Хаак explains:

protected internalозначаетprotectedИЛИ internal

Это очень ясно, когда вы думаете о ключевых слов как объединение доступности , а не пересечение , Таким образом protected interna означает, что метод доступен всем, что может получить доступ к protected метод UNION с все, что может получить доступ к методу internal .

Вот обновленный код:

class A { 
    protected void Test3(){} //available to subclasses of A in any assembly 
    protected internal void Test() { } //Same as protected :(
    public void Test2(){}//available to everyone 
    internal void Test4(){} //available to any class in A's assembly 
} 

class B : A { 
    void TestA() { 
    Test(); //OK 
    } 
} 
//Different assembly 
class C : B { 
    void TestA() { 
    Test4(); //error CS0103: The name 'Test4' does not exist in the current context 
    } 
} 
+0

@lgor: В этом случае, как я смогу использовать другие шесть функций, которые были определены в классе А, сделав их общедоступными? –

+1

Да. см. код для уточнения. –

+0

Мне жаль, что я не смог бы продвинуть это более одного раза. Отличная иллюстрация! – mynameiscoffey

0

Как уже говорили другие, вы, вероятно, хотите использовать композицию вместо наследования.

class A { 
    protected void Foo() { … } 
    protected int Bar() { … } 
} 

class B { 
    private A a; 

    public B() { 
     this.a = new A(); 
    } 

    protected int Bar() { 
     return a.Bar(); 
    } 
} 

class C : B { … } 

Глядя на вашем примере, хотя, я бы вопрос, должен ли C наследовать от B, или должен ли он на самом деле просто содержать ссылку на объект типа B.

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

+0

Да, я думал унаследовать B от C. Я хочу, чтобы A была в отдельной сборке, потому что я помещаю весь мой многоразовый код в это пространство имен. B & C может быть помещен под тем же пространством имен, что и код, зависящий от приложения. Хотя я новичок в реализации ООП. Практика и xprs прекрасно подходят для выбора вариантов того, что нужно делать. Вот что я ищу здесь. –

+0

Будьте осторожны: пространство имен - это не то же самое, что и сборка. – phoog

Смежные вопросы