Ограничение подклассов от наследования определенных методов базового класса - PullRequest
1 голос
/ 20 января 2012
using System;

public class Base
{
    public Base()
    {
    }

    public void M1()
    {
    }

    public void M2()
    {
    }

    public void M3()
    {
    }
}

public class Derived : Base
{
    //this class should get only method 1
}

public class SecondDerived : Base
{
    //this class should get only method 2 and method3
}

Требование: базовый класс содержит 3 метода M1, M2, M3.
Производный класс должен наследовать только M1, а SecondDerived должен наследовать только M2 иM3.

Как это можно сделать?

Ответы [ 4 ]

3 голосов
/ 20 января 2012

Вы не можете сделать это таким образом.Наследование подразумевает отношения «есть».

Если SecondDerived не будет иметь M1(), то оно не будет совместимо со ссылкой на class Base.

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

3 голосов
/ 20 января 2012

Вы не можете выборочно наследовать методы, подобные этому. Производный класс автоматически наследует все открытые методы базового класса. Я предлагаю вам разделить класс Base на два класса:

public class Base1
{
    public Base1()
    {
    }

    public void M1()
    {
    }
}

public class Base2
{
    public void M2()
    {        
    }

    public void M3()
    {       
    }
}

public class First : Base1

public class Second : Base2
0 голосов
/ 04 декабря 2015

Это возможно, добавив устаревший атрибут

public class A
{
    public virtual void M1() { }
    public void M2() { }
    public void M3() { }
}

public class B : A
{
    [Obsolete("You can not use this", true)]
    public sealed override void M1()
    {

    }
}

public class C : B
{
    public void Test()
    {
        // Will show error 
        base.M1();

    }
}
0 голосов
/ 20 января 2012

Невозможно делать то, что вы хотите, с наследованием.

Кажется, у вас нет намерения переопределять, вы просто хотите "наследовать" поведение от базового класса выборочно.Вы можете сделать это, используя отношение «имеет»:

public class Base
{
     internal Base() {} //mark constructor as internal so it can not be used outside your assembly if necessary

     public Foo Mehtod1() {...}
     public Foo Mehtod2() {...}
     public Foo Mehtod3() {...}
}

Затем просто выполните следующее:

class A
{
     private Base internalBase;

     public A() { this.internalBase = new Base(); }

     public Foo Method1() { return this.internalBase.Method1(); }
}

class B
{
     private Base internalBase;

     public A() { this.internalBase = new Base(); }

     public Foo Method2() { return this.internalBase.Method2(); }
     public Foo Method3() { return this.internalBase.Method3(); }
}

ОБНОВЛЕНИЕ: Возможное альтернативное решение -сделайте ваши Base методы класса virtual и переопределите их все в ваших производных классах, добавив NotSupportedException s в те методы, которые вы не хотите, чтобы класс сделал доступными.Мне не очень нравится это решение, но оно имеет то преимущество, что не теряет наследование полиформизма, что может быть полезно, если у вас есть базовая базовая функциональность, которой поделятся все производные классы (в вашем примере вы, похоже, подразумеваете, что они этого не сделают).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...