2016-06-07 61 views
1

说我有一个基类是这样的:你如何让成员无法进入子派生类?

public abstract class MyBaseClass 
{ 
    protected void MyMethod(string myVariable) 
    { 
    //... 
    } 
} 

然后我继承这个类在单独的程序:

public abstract class MyDerivedClass : MyBaseClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    protected void MyMethod() 
    { 
    MyMethod(MyConstantString); 
    } 
} 

我现在要确保从MyDerivedClass继承任何其他类完成无法访问MyBaseClass.MyMethod()方法。 (为了澄清,我仍然希望能够调用MyDerivedClass.MyMethod()没有参数)

我试过使用protected internal但没有奏效。

更新:我试图做到这一点,因为我正在处理的应用程序有一堆使用基类的单独程序。有5种不同的“类型”的程序,每个都执行一个特定的,独立的功能,但它们都有一些我想要抽象到这个基类中的通用代码。通用代码是99%相同的,只是略有不同,这取决于程序调用它的类型。这就是为什么我有我的基类在示例中采用字符串参数,然后消失在派生的基类中,因为该类知道它执行角色x,因此它会相应地告知其基类。

+1

你的意思是说你不希望他们叫它,或者你不希望它们覆盖它吗? –

+0

@MthetheWWatson两者。 – Logan

+2

你无法阻止它被调用。 –

回答

0

这不太可能。这可能表明你的物体设计可能有问题,但这不是一个问题。

你可以尝试多一点卑劣的做法,虽然:

public abstract class MyBaseClass 
{ 
    protected abstract string MyConstantString { get; } 

    protected void MyMethod() 
    { 
    //... 
    } 
} 

public abstract class MyDerivedClass : MyBaseClass 
{ 
    protected override sealed string MyConstantString => "Hello"; 
} 

,或者更通常,只需使用构造函数来传递所需的参数:从MyDerivedClass衍生

public abstract class MyBaseClass 
{ 
    private readonly string myString; 

    protected MyBaseClass(string myString) 
    { 
    this.myString = myString; 
    } 

    protected void MyMethod() 
    { 
    //... 
    } 
} 

public abstract class MyDerivedClass : MyBaseClass 
{ 
    protected MyBaseClass() : base("Hello") {} 
} 

类没有在这两种情况下都可以改变参数,第二种方法从继承角度来看更好一些(基本上,这个类型是一个关于其祖先类型参数的闭包)。

+0

使用构造函数让我足够接近我想要的。我甚至没有考虑过构造函数! – Logan

2

然后,我会在MyDerivedClass而不是继承使用组成。所以这个类的所有派生类都不知道MyBaseClass的方法。类MyBaseClass我会使包可见,所以它不可能使用它。

abstract class MyBaseClass 
{ 
    void MyMethod(string myVariable) 
    { 
    //... 
    } 
} 

abstract class MyDerivedClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    private MyBaseClass baseClass; 

    MyDerivedClass(MyBaseClass baseClass) 
    { 
     this.baseClass = baseClass; 
    } 

    protected void MyMethod() 
    { 
    baseClass.MyMethod(MyConstantString); 
    } 
} 

当然应该改变类名。

+0

代表团可能是去这里的方式,正确的;但是如果你只是在包含类中编写包装器(就像你用MyDerivedClass.MyMethod()演示的那样,它只是调用MyBaseClass.MyMethod()),那么整个目的就会失败。如果包含的类逻辑更复杂,委托只是一种解决方案,因此在包装和包装之间不存在简单的1:1关系。 –

0

您无法停止继承类来调用此方法 - 您已将其设置为protected,因此您的目的是让它可以直接或通过其他子类继承的类访问它。

如果你想保留的继承,你能做的最好的是,如果子类MyDerivedClass调用它抛出一个错误:

public abstract class MyBaseClass 
{ 
    protected void MyMethod(string myVariable) 
    { 
     Console.WriteLine(myVariable); 
    } 
} 

public abstract class MyDerivedClass : MyBaseClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    protected void MyMethod() 
    { 
     base.MyMethod(MyConstantString); 
    } 

    protected new void MyMethod(string myVariable) 
    { 
     throw new Exception("Not allowed"); 
    } 
} 

public class SubDerivedClass : MyDerivedClass 
{ 
    static readonly string MyConstantString = "Hello"; 
    public void Foo() 
    { 
     MyMethod(MyConstantString); 
    } 
} 

Foo()被称为SubDerivedClass,它会调用MyMethodDerivedClass,这将抛出异常。

相关问题