我们可以在父 class 中定义一个方法,该方法可以在子内部调用但不能在另一个子内部调用吗
can we define a method in parent class which can be called within a child but not the other one
i 运行 陷入一个问题,我想在父 class (A) 中有一个方法 (M),然后 B 和 C 扩展 class A。在这种情况下,我希望 B 可以访问 method(M) 而不是 C 。有什么解决办法吗?
public class A
{
????? string M()
{
return "Hi there";
}
}
public class B:A
{
}
public class C:A
{
}
B newClassB = new B();
C newClassC = new C();
Console.WriteLine(newClassB.M()); //the correct one
Console.WriteLine(newClassC.M()); //the incorrect one
in this situation i want method(M) can be accessible by B but not C . any solution?
正如我在评论中所说,你不能那样做,但你可以这样做:
class A
{
public virtual bool Before() { return false; }
public void BaseMethod ()
{
if(Before())
Console.WriteLine("Called method AMethod");
}
}
class B : A
{
public override bool Before() {return true; }
}
class C : A
{
}
void Main()
{
var c = new C();
var b = new B();
c.BaseMethod();
b.BaseMethod();
}
在这种情况下,BaseMethod()
将对 C
实例执行无效。
其他一些答案似乎鼓励您违反 Liskov Substitution Principle,这是非常糟糕的做法,只会导致糟糕的代码。
你这里有一个设计问题。如果您希望 C
继承 A
那么它的行为应该与 A
完全相同,但具有添加或修改的功能。
里氏原理指出:
"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."
对于您想做的事情,您可能可能破坏事物。假设您有一个方法接受您的父 class A
,但您将派生的 class C
传递给它。当您的方法尝试调用 C.M()
时会发生什么?
您需要做的是重新考虑您的 class 设计。如果您不应该从 C
调用 M()
,那么 C
真的 是 A
的子类型吗?
您问题的代码非常含糊,因此我无法针对您的 class 结构提出替代解决方案,但如果您能让您的代码不那么含糊,我会进行编辑。
好的,一个有用的答案(我之前的答案不是)。
不,你不能也不应该这样做,因为其他答案和评论中已经指出了 Liskov 替换原则。
然而,在某些情况下它是合理的,事实上,NET 中的某些 类 确实实现了以下模式:
public class A
{
public virtual bool CanCallM => true;
public void M() {
if (!CanCallM) throw new NotSupportedException();
//do whatever }
}
public class B: A { }
public class C: A
{
public override bool CanCallM => false;
}
漂亮吗?不多,但是您确实为消费者提供了一种方法,可以预先知道 是否可以调用 M
,并且您确保在运行时 c.M
失败。
我个人更喜欢这种模式,而不是什么都不做,因为后者可能是代码中的错误;有人打电话给 M
,期望未达到。
i 运行 陷入一个问题,我想在父 class (A) 中有一个方法 (M),然后 B 和 C 扩展 class A。在这种情况下,我希望 B 可以访问 method(M) 而不是 C 。有什么解决办法吗?
public class A
{
????? string M()
{
return "Hi there";
}
}
public class B:A
{
}
public class C:A
{
}
B newClassB = new B();
C newClassC = new C();
Console.WriteLine(newClassB.M()); //the correct one
Console.WriteLine(newClassC.M()); //the incorrect one
in this situation i want method(M) can be accessible by B but not C . any solution?
正如我在评论中所说,你不能那样做,但你可以这样做:
class A
{
public virtual bool Before() { return false; }
public void BaseMethod ()
{
if(Before())
Console.WriteLine("Called method AMethod");
}
}
class B : A
{
public override bool Before() {return true; }
}
class C : A
{
}
void Main()
{
var c = new C();
var b = new B();
c.BaseMethod();
b.BaseMethod();
}
在这种情况下,BaseMethod()
将对 C
实例执行无效。
其他一些答案似乎鼓励您违反 Liskov Substitution Principle,这是非常糟糕的做法,只会导致糟糕的代码。
你这里有一个设计问题。如果您希望 C
继承 A
那么它的行为应该与 A
完全相同,但具有添加或修改的功能。
里氏原理指出:
"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."
对于您想做的事情,您可能可能破坏事物。假设您有一个方法接受您的父 class A
,但您将派生的 class C
传递给它。当您的方法尝试调用 C.M()
时会发生什么?
您需要做的是重新考虑您的 class 设计。如果您不应该从 C
调用 M()
,那么 C
真的 是 A
的子类型吗?
您问题的代码非常含糊,因此我无法针对您的 class 结构提出替代解决方案,但如果您能让您的代码不那么含糊,我会进行编辑。
好的,一个有用的答案(我之前的答案不是)。
不,你不能也不应该这样做,因为其他答案和评论中已经指出了 Liskov 替换原则。
然而,在某些情况下它是合理的,事实上,NET 中的某些 类 确实实现了以下模式:
public class A
{
public virtual bool CanCallM => true;
public void M() {
if (!CanCallM) throw new NotSupportedException();
//do whatever }
}
public class B: A { }
public class C: A
{
public override bool CanCallM => false;
}
漂亮吗?不多,但是您确实为消费者提供了一种方法,可以预先知道 是否可以调用 M
,并且您确保在运行时 c.M
失败。
我个人更喜欢这种模式,而不是什么都不做,因为后者可能是代码中的错误;有人打电话给 M
,期望未达到。