Я пытаюсь реализовать множественное наследование. Как я могу это сделать - PullRequest
1 голос
/ 17 мая 2010

Я создал класс скажем А, в котором некоторые функции определены как защищенные.

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

Я хочу, чтобы класс B имел доступ ко всем защищенным функциям, определенным в классе A, но класс 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.
}

Ответы [ 4 ]

4 голосов
/ 17 мая 2010

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

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

Даже Руководство по программированию на C # в MSDN ошибается:

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

Фил Хаак объясняет :

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

Это очень ясно, когда вы думаете о ключевые слова как союз доступности а не пересечение. таким образом protected interna означает, что метод доступны всем, кто может получить доступ protected метод СОЮЗ с все, что может получить доступ к 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
  }
 }
2 голосов
/ 17 мая 2010

Похоже, вам следует использовать Composition, а не Inheritance.

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

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

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

1 голос
/ 17 мая 2010

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

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

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

0 голосов
/ 17 мая 2010

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

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.

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

...