我想在开始之前我就知道这个问题的答案,但在谷歌上进行了多次搜索后,我找不到明确的答案。
这个问题假设我们使用 Ecmascript 6 及更高版本中的类模式。
我最初的信念是方法压倒一切
另一方面,方法遮蔽(不仅仅是块作用域“变量遮蔽”-在面向对象编程中,是一种语言功能,允许 子类或子类提供特定的实现 其超类或父类之一已提供的方法 类。 维基百科
Wikipedia)似乎只在像 C# 这样的强类型语言的上下文中才有意义,它允许您设置“子类”的实例' 作为“基类”类型,这意味着实例将恢复为基类方法,而不是任何“影子”方法。
public abstract class BaseClass
{
public virtual void shadowedMethod()
{
Console.WriteLine("This is the BaseClass version");
}
}
public class DerivedClass : BaseClass
{
public new void shadowedMethod()
{
Console.WriteLine("This is the Derived child class");
}
}
public class Program
{
public static void Main()
{
BaseClass instance = new DerivedClass(); // Because BaseClass type is set instead of DerivedClass
instance.shadowedMethod(); // It prints "This is the BaseClass version"
}
}
所以问题是:为什么大多数 JS 线程和文档ECMA 标准 交替使用覆盖和影子(但倾向于使用影子)?我们不应该只使用一个术语来避免混乱吗?在 Javascript 中,重写方法和隐藏方法之间实际上存在细微差别吗?
看起来,派生类(作为基类)中具有相同名称的所有方法都是“影子方法”,并且接受相同参数(因此创建相同接口)的方法的子集也被“重写”方法,因为“重写的成员必须接受相同的数据类型和参数数量”。 (
看这篇文章)
如果派生类上的方法使用相同的签名(接受相同的参数),则该方法将覆盖父类/基类:
class BaseClass {
overriddenMethod(a) {
return a;
}
}
class DerivedClass {
overriddenMethod(a) {
return 2*a;
}
}
但如果派生类方法接受不同的参数,这只是“影子”:
class BaseClass {
overriddenMethod(a) {
return a;
}
}
class DerivedClass {
overriddenMethod(a, b) { // This is not overriding because it accepts different parameters.
return a + b;
}
}
更详细地说,它是“阴影”的,因为 Javascript 是一种原型语言,这意味着一切都是对象(甚至类定义),因此一切最终都是对象上的变量,因此进一步“变量阴影”外部作用域上的变量沿着原型链向上。
阴影:正如我在爪哇谷功夫故事中所解释的,考虑我们将一个灯笼放在另一个灯笼前面。我们只能看到第二个灯笼发出的光。
阴影适用于变量、静态和实例方法。
重写:简单来说,重写是一种影子,当子类实现父类的相同方法时发生。
public class ShadowingExample {
private int num = 10; // Class-level variable
public void shadowMethod() {
int num = 20; // Local variable shadowing the class-level variable
System.out.println("Local variable num: " + num); // Prints the value of the local variable
}
}
参考:免责声明:我是发布的参考链接的作者