当前位置: 首页 > 知识库问答 >
问题:

为什么在扩展类(Java)中访问成员和函数有差异?

王磊
2023-03-14

因此,我在尝试Java中的一些基本封装时发现,从扩展类内部访问成员和函数的方式是不同的。我想说的是:

public class A {
  int i = 10;
  public void print() {
    System.out.println(" inside A ");
  }
}

public class B extends A{
  int i = 20;
  public void print() {
    System.out.println(" in B");
  }

  public static void main(String args[]) {
    A a = new B();
    a.print();
    System.out.println(a.i);
  }
}

在上面的例子中,对于当前类的对象(扩展超级类的对象),在访问超级类的成员的同时调用当前类的方法。那么,这是什么原因呢?或者,更笼统地说,当我说

A a = new B()

我是说,在记忆层面发生了什么?

共有1个答案

仲承福
2023-03-14

这是因为在Java中,所有非静态、非final和非private方法在默认情况下都是虚拟的。

来自维基百科虚拟函数:

在面向对象编程中,当派生类从基类继承时,派生类的对象可以通过基类类型的指针或引用而不是派生类类型来引用。如果有被派生类重写的基类方法,则由此类引用或指针实际调用的方法可以根据指针或引用的声明类型“早期”绑定(由编译器),也可以根据所引用对象的实际类型“后期”绑定(即由语言的运行时系统)。

虚函数“延迟”解析。如果所讨论的函数在基类中为“virtual”,则无论指针或引用的声明类型如何,都将根据所引用对象的实际类型调用该函数的最派生类的实现。如果它不是“virtual”,则“早期”解析该方法,并根据指针或引用的声明类型选择调用的函数。

虚函数允许程序调用在代码编译时不一定存在的方法。

 类似资料:
  • 我在Kotlin文件中定义了扩展函数。 其中是(生成的)java类。现在,我想用正常的java代码访问它: 然而,那是行不通的。IDE将无法识别方法,编译失败。

  • 问题内容: 我想对此进行一些讨论,但无法推断出我的情况的答案。仍然需要帮助。 这是我的代码: 在上面的示例中,下面的一些定义似乎令人困惑: 问题: 为什么我不能从子类实例(对象)访问受保护的成员()? 问题答案: 作为声明类的子类的其他包中的类只能访问其自己的继承成员。 …但不是其他对象的继承成员。

  • 注意:如果friend函数只是在类中声明并在外部实现,那么Clang和GCC都会拒绝该代码。

  • 问题内容: 我观察到外部类可以访问内部类的私有实例变量。这怎么可能?这是演示相同代码的示例代码: 为什么允许这种行为? 问题答案: 内部类只是一种将真正属于原始外部类的功能完全分开的方法。当你有两个要求时,可以使用它们: 如果是在单独的类中实现的,那么外部类中的某些功能将最为清晰。 即使在单独的类中,该功能也与外部类的工作方式紧密相关。 鉴于这些要求,内部类可以完全访问其外部类。由于它们基本上是外

  • 问题内容: 我只是编写了一个示例程序来查看 删除此文件* 的行为 * 问题 在fun()中执行 删除操作 后,如何在fun()中使用此指针访问func_2()? 现在主要在删除该指针时如何执行 obj- > fun_2? 如果在杀死该对象后能够访问函数成员,那么为什么数据成员的数据为零‘0’? m使用linux ubuntu和g ++编译器 问题答案: 让我们将其与类似的szenario进行比较:

  • 问题内容: 我正在研究TypeScript中私有成员的实现,但我感到有些困惑。Intellisense不允许访问私有成员,但是在纯JavaScript中,仅此而已。这使我认为TS无法正确实现私有成员。有什么想法吗? 问题答案: 就像类型检查一样,成员的隐私仅在编译器中强制执行。 私有属性被实现为常规属性,并且不允许类外的代码对其进行访问。 为了使某些东西真正成为类的私有对象,它不能成为该类的成员,