我对多态性和类对象感到困惑[重复]

Posted

技术标签:

【中文标题】我对多态性和类对象感到困惑[重复]【英文标题】:I am confused about Polymorphism and object of class [duplicate] 【发布时间】:2018-03-18 02:20:26 【问题描述】:
class A 
class B extends A

A objectX = new B();

最后一行是什么意思?是A类的对象还是B类的对象。

实例和对象的含义相同吗? objectX 是 A 的实例还是 B 的实例?

当我们运行 objectX.SomeMethod.编译器会检查什么?还是会在运行时检查方法?

  class A
  class B extends A
  public class Main
  public static void main(String[] args)  
  A objectX =  new B(); 
  System.out.println(objectX instanceof B);//line 1
  System.out.println(objectX instanceof A);//line 2
  
  

如果我运行上面的代码,为什么它对第 1 行和第 2 行给出正确的结果。objectX 指向 B。为什么 objectX 是 A 的实例?

【问题讨论】:

它是A类型的引用,引用B类型的对象。也就是说你只能调用方法和A类中定义的字段。 如果你用代码展示你的问题,而不是试图用文字来描述它,会容易得多。 访问:***.com/questions/13077009/… 访问:***.com/questions/13077009/… 【参考方案1】:

检查这个例子:

Object aStringObject=new String();

在您的场景中,A 是 Object(所有对象的超类),B 是 String。因此,对于您的问题,aStringObject 现在是对 String 类对象的引用(或指针)。它被定义为 Object 类型的引用,因此它可以指向不同类型的对象而不仅仅是字符串。因此,如果您想避免代码中的编译错误,您只能将其用作对象。

如果你知道它是一个字符串(你指向的实例是字符串类型),你可以将它转换为一个字符串,这样就可以了。在上面的例子中你可以这样做:

String aStringString = (String) aStringObject; 

但是如果那个对象不是你刚刚声明的东西,你不能确定你能做到这一点,并且通过它的声明它可以是一个字符串,但它也不能是一个。

在你的情况下:

 A objectX = new B();

objectX 是 B 类型的一个实例,但引用(指针)是用 A 类型声明的,因此您可以安全地(无需强制转换)将它用作 A 类型对象,并且它会起作用,因为 B 类型的所有对象也是 A :) 你可以这样做 ((B)objectX).bMethod() 因为你知道它实际上是 B 但它不安全,因为它可以是这样声明的 A。

【讨论】:

无论如何,您永远都不需要将 objectX 转换为“A”——并不是说您可以安全地将它用作 A,而是 A 是的,这就是我的意思。您将它声明为 A 并且它是 A,因为 B 是 A。但是如果您想将其用作 B,则需要强制转换它。而且你不能安全地做到这一点,因为定义不能保证这个 objectX 是一个 B(你可能知道它,因为你创建了实例)。我写(没有强制转换)只是为了澄清,但我想它并没有让它更清楚:) 我在解释中感到困惑 当然可以使用instanceof判断是否为B【参考方案2】:
A objectX = new B();

这里的objectX是A类(父类)的引用,可以持有A类或B类(子类)的对象。

=的右边即new B(),是B类(子类)的对象。

永远记住在java中对象是使用new关键字创建的。所以左侧部分是参考,右侧部分是对象。

当你调用这样的方法时

objectX.someMethod()

在这种情况下,第一个编译器检查方法是否存在于引用类(A类)中。如果不存在则显示错误。

如果找到方法,则将从子类(B 类)调用方法。因为方法绑定是在运行时完成的。

【讨论】:

以上是关于我对多态性和类对象感到困惑[重复]的主要内容,如果未能解决你的问题,请参考以下文章

Python面向对象:继承多态类属性和类方法单例

Python面向对象:继承多态类属性和类方法单例

多态性 - 重载/覆盖

Java动态绑定与多态

是列表 List的子类 ?为什么Java泛型不是隐式多态的?

新手入门学Python基础—多态类属性和类方法