我试图阻止我的Base类派生它的一个方法,但似乎不可能按照我喜欢的方式去做,我认为我做错了。
你可以帮忙吗? :) 我真的想成功使用密封关键字!以下是一些代码:
public class BaseClass
{
public void MyMethod1(string input)
{
// Doing stuff here
}
public sealed void MyMethod2(string input)
{
// Doing stuff here
}
}
public class DerivedClass : BaseClass
{
// Other fields and stuff over there
}
发生的事情是有问题的,关键字密封不允许在第一级推导中的方法。 我只有一个派生级别,而我正在寻找的是避免在DerivedClass中派生MyMethod2。
但它似乎没有问题:/ 有任何建议或更正吗?
提前致谢:)
编辑:经过多次评论和午餐暂停后,我会尝试明确我的问题!
我真正想做的是阻止我的班级使用“她”继承的方法之一。 有些人提到使用合成而不是继承,因为它似乎误解了它的含义。
我认为组合只存在于UML而不是代码中。 在C#代码中听起来像什么?
答案 0 :(得分:4)
如果这是第一个级别,除非标记为virtual
或abstract
,否则它不会被派生类覆盖。
public class BaseClass
{
public virtual void MyMethod1(string input)
{
// Doing stuff here
}
public void MyMethod2(string input)
{
// Doing stuff here
}
}
public class DerivedClass : BaseClass
{
public override void MyMethod1(string input){..}
/// MyMethod2 is not overridable
}
根据你下面的评论,你真正想要的似乎是构图,而不是继承;也就是说DerivedClass
应该能够访问BaseClass
上的某些功能,但不应该以任何方式更改它。对于您的课程示例,这可能如下所示。
public class CompositeFunctionality
{
public void MyMethod1(string input)
{
// Doing stuff here
}
}
public class BaseClass
{
private CompositeFunctionality composite = new CompositeFunctionality();
public void MyMethod2(string input)
{
// this is accessible in the base class
composite.MyMethod1();
}
}
public class DerivedClass : BaseClass
{
public void MyMethod3(string input)
{
// do whatever you want
// but composite is not accessible here
}
}
答案 1 :(得分:4)
您只能密封覆盖基类中的虚方法的方法/属性。您的MyMethod2
不是虚拟的,因此无法密封。事实上,它并不是因为它不是虚拟的,所以它是隐含的!
答案 2 :(得分:1)
您需要其他级别的继承才能使用sealed
。您可以在基类中标记方法virtual
,在第二个类中标记override sealed
。
你可以制作“绝对基础”抽象,所以不可能实例化它,然后继承它来实现并密封它:
public abstract class VeryBaseClass
{
public abstract void MyMethod2(string input);
}
public class BaseClass : VeryBaseClass
{
public override sealed void MyMethod2(string input)
{
}
}
public class DerivedClass : BaseClass
{
// Other fields and stuff over there
}
但是像@Jenish says一样,默认情况下C#中的方法是密封的。
相反,为了能够覆盖方法,无论如何都必须将其标记为virtual
,因此您的问题似乎根本不是问题。只需将MyMethod1
标记为virtual
,以便可以覆盖它,MyMethod2
将保持非虚拟状态,因此根本不可覆盖。
答案 3 :(得分:0)
sealed关键字隐含在基类中的任何方法中,该方法不是虚拟的或抽象的(因此可以覆盖)。
有关详细信息,请参阅此link on MSDN
答案 4 :(得分:0)
试试这个..
class Base
{
public virtual void Test() { ... }
}
class Subclass1 : Base
{
public sealed override void Test() { ... }
}
class Subclass2 : Subclass1
{
public override void Test() { ... } // FAILS!
// If `Subclass1.Test` was not sealed, it would've compiled correctly.
}
答案 5 :(得分:0)
我正在重命名方法以便更好地理解。
public class BaseClass
{
public void MethodToBeInherited(string input)
{
// Doing stuff here
}
public void MethodNotToBeInherited(string input)
{
// Doing stuff here
}
}
public class DerivedClass : BaseClass
{
// Other fields and stuff over there
//MethodoBeInherited should be available
//MethodNotToBeInherited should not be available
}
使用这种层次结构(是关系)无法实现您想要的条件,因为DervicedClass是BaseClass。因此,在继承规则上,您必须能够访问所有BaseClass公共方法。
但是有一种方法可以解决这个问题 - 有关系。 它不可能继承并实现你想要的东西,因为你将破坏继承规则。因此,使派生类由基类组成,您将能够实现它。
interface I
{
void MethodToBeInherited(string input)
}
class BaseClass
{
public void MethodToBeInherited(string input)
{
// Doing stuff here
}
public void MethodNotToBeInherited(string input)
{
// Doing stuff here
}
}
class DerivedClass : I
{
public void MethodToBeInherited(string input)
{
b.MethodToBeInherited(input);
}
private BaseClass b;
}