问题描述
对于方法,父类有方法b和a,其中b调用a,子类重写了a方法。通过子类对象调用b方法时,调用的是子类重写的a方法。但是对于变量,父类方法a中访问了公共变量var,子类覆盖了公共变量var。通过子类对象调用方法a,访问的却是来自继承的变量,不是重写的变量。不知道为什么会有这种差异呢?
解决方案
解决方案二:
多态的问题,多态是针对子类重写父类的方法的,但对变量则没有多态。比如Aa=newB();是创建了一个子类对象并把它当成父类对象A用也就是父类引用指向子类对象此时,引用变量a有2个类型,编译时的类型为A,运行时的类型为B.在代码编译过程中,a只能调用属于A的方法.不能调用B类里面的方法.注意,由于继承关系,如果B重写了A的某个方法,比如说eat(),而在代码编译过程中,a.eat()调用的是A的eat(),但在程序运行时,却运行的是B的eat().这就是多态比如Animala=newTiger();Tiger继承并重写了Animal的eat()方法.这也是父类引用指向子类对象.首先,a是一只老虎.但不幸的是,Animala=newTiger();也就是说a虽然有了老虎的实质,就是说有了老虎的爪子,身材.....,但却没有老虎的名分.它虽然身体是老虎,但名字或者说它的类别却是动物,而不是老虎.而作为动物的定义,你当然不能使用属于老虎的定义的方法.比如说,虽然二者都有吃的行为,但老虎吃肉,动物都吃肉么?所以虽然a实质上是老虎,但在书面描述a的行为时,你只能使用动物的定义.这个阶段就相当于代码的编译的阶段.而此时a的类型为编译时的类型-动物.而如果具体实施吃的行为时,比如说给a喂吃的,虽然书面定义了a只能有动物的笼统的吃的方法,比如说用嘴,没有规定要吃肉.但是现在是具体操作了,由于a实质上是老虎,所以a实质上履行的还是老虎的吃的方法.具体的吃的过程,就相当于程序的运行的阶段.而此时a的类型为运行时的类型-老虎
解决方案三:
楼主怎么写的,我按照你的描述写的代码没问题packagelearning;classParent{publicintvar=1;publicvoida(){System.out.println("Parent'varis:"+this.var);}publicvoidb(){this.a();}}classChildextendsParent{publicintvar=2;publicvoida(){System.out.println("Child'varis:"+this.var);}}publicclassExtendsTest{publicstaticvoidmain(String[]args){newChild().b();}}
输出为:Child'varis:2
解决方案四:
引用1楼ghx287524027的回复:
多态的问题,多态是针对子类重写父类的方法的,但对变量则没有多态。比如Aa=newB();是创建了一个子类对象并把它当成父类对象A用也就是父类引用指向子类对象此时,引用变量a有2个类型,编译时的类型为A,运行时的类型为B.在代码编译过程中,a只能调用属于A的方法.不能调用B类里面的方法.注意,由于继承关系,如果B重写了A的某个方法,比如说eat(),而在代码编译过程中,a.eat()调用的是A的eat(),但在程序运行时,却运行的是B的eat().这就是多态比如Animala=newTiger();Tiger继承并重写了Animal的eat()方法.这也是父类引用指向子类对象.首先,a是一只老虎.但不幸的是,Animala=newTiger();也就是说a虽然有了老虎的实质,就是说有了老虎的爪子,身材.....,但却没有老虎的名分.它虽然身体是老虎,但名字或者说它的类别却是动物,而不是老虎.而作为动物的定义,你当然不能使用属于老虎的定义的方法.比如说,虽然二者都有吃的行为,但老虎吃肉,动物都吃肉么?所以虽然a实质上是老虎,但在书面描述a的行为时,你只能使用动物的定义.这个阶段就相当于代码的编译的阶段.而此时a的类型为编译时的类型-动物.而如果具体实施吃的行为时,比如说给a喂吃的,虽然书面定义了a只能有动物的笼统的吃的方法,比如说用嘴,没有规定要吃肉.但是现在是具体操作了,由于a实质上是老虎,所以a实质上履行的还是老虎的吃的方法.具体的吃的过程,就相当于程序的运行的阶段.而此时a的类型为运行时的类型-老虎
你说了这么多还是没回答LZ的问题
解决方案五:
引用3楼jsshizhanab的回复:
Quote: 引用1楼ghx287524027的回复:
多态的问题,多态是针对子类重写父类的方法的,但对变量则没有多态。比如Aa=newB();是创建了一个子类对象并把它当成父类对象A用也就是父类引用指向子类对象此时,引用变量a有2个类型,编译时的类型为A,运行时的类型为B.在代码编译过程中,a只能调用属于A的方法.不能调用B类里面的方法.注意,由于继承关系,如果B重写了A的某个方法,比如说eat(),而在代码编译过程中,a.eat()调用的是A的eat(),但在程序运行时,却运行的是B的eat().这就是多态比如Animala=newTiger();Tiger继承并重写了Animal的eat()方法.这也是父类引用指向子类对象.首先,a是一只老虎.但不幸的是,Animala=newTiger();也就是说a虽然有了老虎的实质,就是说有了老虎的爪子,身材.....,但却没有老虎的名分.它虽然身体是老虎,但名字或者说它的类别却是动物,而不是老虎.而作为动物的定义,你当然不能使用属于老虎的定义的方法.比如说,虽然二者都有吃的行为,但老虎吃肉,动物都吃肉么?所以虽然a实质上是老虎,但在书面描述a的行为时,你只能使用动物的定义.这个阶段就相当于代码的编译的阶段.而此时a的类型为编译时的类型-动物.而如果具体实施吃的行为时,比如说给a喂吃的,虽然书面定义了a只能有动物的笼统的吃的方法,比如说用嘴,没有规定要吃肉.但是现在是具体操作了,由于a实质上是老虎,所以a实质上履行的还是老虎的吃的方法.具体的吃的过程,就相当于程序的运行的阶段.而此时a的类型为运行时的类型-老虎你说了这么多还是没回答LZ的问题
他第一句话就回答了
解决方案六:
引用4楼tianyutaizi的回复:
Quote: 引用3楼jsshizhanab的回复:
Quote: 引用1楼ghx287524027的回复:
多态的问题,多态是针对子类重写父类的方法的,但对变量则没有多态。比如Aa=newB();是创建了一个子类对象并把它当成父类对象A用也就是父类引用指向子类对象此时,引用变量a有2个类型,编译时的类型为A,运行时的类型为B.在代码编译过程中,a只能调用属于A的方法.不能调用B类里面的方法.注意,由于继承关系,如果B重写了A的某个方法,比如说eat(),而在代码编译过程中,a.eat()调用的是A的eat(),但在程序运行时,却运行的是B的eat().这就是多态比如Animala=newTiger();Tiger继承并重写了Animal的eat()方法.这也是父类引用指向子类对象.首先,a是一只老虎.但不幸的是,Animala=newTiger();也就是说a虽然有了老虎的实质,就是说有了老虎的爪子,身材.....,但却没有老虎的名分.它虽然身体是老虎,但名字或者说它的类别却是动物,而不是老虎.而作为动物的定义,你当然不能使用属于老虎的定义的方法.比如说,虽然二者都有吃的行为,但老虎吃肉,动物都吃肉么?所以虽然a实质上是老虎,但在书面描述a的行为时,你只能使用动物的定义.这个阶段就相当于代码的编译的阶段.而此时a的类型为编译时的类型-动物.而如果具体实施吃的行为时,比如说给a喂吃的,虽然书面定义了a只能有动物的笼统的吃的方法,比如说用嘴,没有规定要吃肉.但是现在是具体操作了,由于a实质上是老虎,所以a实质上履行的还是老虎的吃的方法.具体的吃的过程,就相当于程序的运行的阶段.而此时a的类型为运行时的类型-老虎你说了这么多还是没回答LZ的问题
他第一句话就回答了
哦是哦