编译通过我能理解,但是为什么运行的时候调的是子类的方法,参数却可以传进去?
还有 可以解释下,为什么父类调方法 可以运行子类的方法吗。
Base base =new Sub();//意思是new Sub()是创建一个Sub类的空间A,然后这个空间A地址是赋值给base,调用base.print()也就是调用空间A的print,实际上空间A的print就是sub.print
父类在new新的对象时,new的是子类,所以向上转型,参数的类型也匹配。这样就可以传进去了。
父类调方法,根据它new的对象和参数的类型来决定运行子类方法还是父类方法
这个很好理解,你把base看成动物,sub当成人,
人继承了动物,并重写了造人的方法,你不要被string...a和string[]a迷惑了,这就当是2个不同的类型int和double
当你用动物去构建人的时候当然是用动物里面的函数传入string或string[]都可以
但是你用人去构建人的时候只能传string[]
在1注释里,base对象属于上转型对象,上转型对象为父类声明、子类实例化的对象,他与父类声明并实例化的对象相比,区别在于前者可以调用子类重写的方法,而后者不可以。上转型对象与子类声明并实例化的对象相比,区别在于前者不能调用子类新增的变量和方法,而后者可以。所以1里因为子类里的print方法重写了父类的print方法,自然上转型对象应该调用的是子类的方法并输出Subprint了。谢谢楼主细心阅读完
父类引用指向子类对象时:
1、若子类覆盖了某方法,则父类引用调用子类重新定义的新方法
2、若子类未覆盖某方法,则父类引用调用父类本身的旧方法
3、若子类覆盖了某属性,但父类引用仍调用父类本身的旧属性
4、若子类未覆盖某属性,则父类引用调用父类本身的旧属性
5、父类引用不能访问子类新定义的方法
因为java的继承机制(规范),子类重写父类方法会覆盖父类的方法
你是想说父类调用子类方法么?如果直接调用子类对象的方法也可以,但是会造成循环依赖等问题(并且该父类只能调用已知的子类),如非必要,尽量不要这样做。
还有一种方法比较安全,就是把被调用的方法设置为抽象方法,让子类继承。这样就不会循环依赖,也不会限定指定的子类。
PS:抽象方法在抽象类里可以是protected,但在接口里只能是public。
参数可以传递原因:调用可变参数的方法时,编译器为该可变参数隐藏创建一个数组,所以子类可以接收。
父类引用调用子类方法原因:面向对象的特征之一,多态;其实主要看的不是引用,而是要看具体实例,因为实例是子类,
所以会先找子类的方法,如果子类没有才会找父类的。