黑马程序员技术交流社区
标题:
关于继承 多态的问题
[打印本页]
作者:
NewDemo
时间:
2014-5-3 18:12
标题:
关于继承 多态的问题
本帖最后由 NewDemo 于 2014-5-4 00:40 编辑
{:2_31:}困惑一天了,
当局者迷,求搭救
class Base {
private int i = 2;
Base() {
System.out.println("base:" + this.i); //
this.display();// 这里是创建子类对象时构造函数用到了父类的构造函数所以调用到了父类自身的方法,结果却是调用了子类的方法,怎么这里会出现覆盖呢?
this.show();// 如果上句存在覆盖,那么这句话如何解释?
}
public void display() {
System.out.println("base display:" + this.i);
}
public static void show() {
System.out.println("base show");
}
}
class Derived extends Base {
public int i = 22;
public Derived() {
super();
i = 222;
}
public void display() {
System.out.println("derived display:" + i);
}
public static void show() {
System.out.println("derived show");
}
}
public class Test3 {
public static void main(String[] args) {
new Derived().display();
// 打印结果:base:2
// derived display:0
// base show
// derived display:222
Base base = new Derived();// 父类引用指向子类对象,典型的多态
base.show();
base.display();// 多态,子类方法覆盖了父类方法,所以运行了子类的方法
// 打印结果:base:2
// derived display:0
// base show
// base show
// derived display:222
}
}
复制代码
作者:
fei_xiong
时间:
2014-5-3 19:30
在多肽中只要出现覆盖方法,如果不是静态方法,那么就会调用子类的方法
可以记住:
只有非静态的方法,才会在多肽中出现调用子类方法的事情
其他的成员变量了,静态方法了,都是父类的
作者:
skill20
时间:
2014-5-3 19:41
多态在子父类中的成员上的体现的特点:
1,成员变量:在多态中,子父类成员变量同名。
在编译时期:参考的是引用型变量所属的类中是否有调用的成员。(编译时不产生对象,只检查语法错误)
运行时期:也是参考引用型变量所属的类中是否有调用的成员。
简单一句话:无论编译和运行,成员变量参考的都是引用变量所属的类中的成员变量。
再说的更容易记忆一些:成员变量 --- 编译运行都看 = 左边。
2,成员函数。
编译时期:参考引用型变量所属的类中是否有调用的方法。
运行事情:参考的是对象所属的类中是否有调用的方法。
为什么是这样的呢?因为在子父类中,对于一模一样的成员函数,有一个特性:覆盖。
简单一句:成员函数,编译看引用型变量所属的类,运行看对象所属的类。
更简单:成员函数 --- 编译看 = 左边,运行看 = 右边。
3,静态函数。
编译时期:参考的是引用型变量所属的类中是否有调用的成员。
运行时期:也是参考引用型变量所属的类中是否有调用的成员。
为什么是这样的呢?因为静态方法,其实不所属于对象,而是所属于该方法所在的类。
调用静态的方法引用是哪个类的引用调用的就是哪个类中的静态方法。
简单说:静态函数 --- 编译运行都看 = 左边。
作者:
张然龙
时间:
2014-5-3 19:58
本帖最后由 张然龙 于 2014-5-3 20:00 编辑
首先 多态的特性就是父类引用指向子类对象。当子类对象覆盖了父类中的方法时,利用多态特性,可以调用子类中覆盖后的方法, 而成员变量不会被覆盖!
根据传入不同的子类,调用相同的函数,从而调用不同的代码,这就是多态
详细请看注释 代码如下↓
class A
{
int num=1;
public static void show()
{
System.out.println("父类静态show");
}
public void show1()
{
System.out.println("父类show");
}
}
class B extends A
{
int num=2;
public static void show()
{
System.out.println("B子类静态show");
}
public void show1()
{
System.out.println("B子类show");
}
}
class C extends A
{
int num=3;
public static void show()
{
System.out.println("C子类静态show");
}
public void show1()
{
System.out.println("C子类show");
}
}
class Show
{
public static void method(A a)
{
a.show();
a.show1();
}
}
class Demo3
{
public static void main (String args[])
{
A d=new B();
System.out.println(d.num);//多态不能覆盖父类中的成员变量!毕老师说了变量看左边的,方法看右边覆盖后的!
Show.method(new B());//根据传入不同的子类,调用相同的函数,从而调用不同的代码,这就是多态
Show.method(new C());
}
}
复制代码
作者:
NewDemo
时间:
2014-5-3 21:30
skill20 发表于 2014-5-3 19:41
多态在子父类中的成员上的体现的特点:
1,成员变量:在多态中,子父类成员变量同名。
在编译时期:参考的 ...
{:2_31:}这个粘贴。。
作者:
wyqs92
时间:
2014-5-3 21:33
这个问题不错。。
class Base {
private int i = 2;
Base() {
System.out.println("base:" + this.i); //
this.display();// 这里是创建子类对象时构造函数用到了父类的构造函数所以调用到了父类自身的方法,结果却是调用了子类的方法,怎么这里会出现覆盖呢?//这是因为函数的特性:覆盖。这时的this指的是子类对象。多态在成员调用上的特点,成员函数:编译看左边,运行看右边
this.show();// 如果上句存在覆盖,那么这句话如何解释?//当调用的是静态函数时,参考的是引用型变量所属类中的方法。你先调用父类的构造函数,所以是调用父类中的show();
}
public void display() {
System.out.println("base display:" + this.i);
}
public static void show() {
System.out.println("base show");
}
}
class Derived extends Base {
public int i = 22;
public Derived() {
super();
i = 222;
}
public void display() {
System.out.println("derived display:" + i);
}
public static void show() {
System.out.println("derived show");
}
}
public class Test3 {
public static void main(String[] args) {
new Derived().display();
// 打印结果:base:2
// derived display:0
// base show
// derived display:222
Base base = new Derived();// 父类引用指向子类对象,典型的多态
base.show();
base.display();// 多态,子类方法覆盖了父类方法,所以运行了子类的方法
// 打印结果:base:2
// derived display:0
// base show
// base show
// derived display:222
}
}
复制代码
多态的出现在成员调用上的特点:
1,成员变量
编译时期:参考的是引用型变量所属的类中是否有调用的成员变量,如果有,编译通过,如果没有编译失败。
运行时期:调用的也是引用型变量所属类中的成员变量。
简单说:编译和运行都看等号的左边。
其实这种情况不多见。
2,成员函数。
编译时期;参考的是引用型变量所属的类中是否有调用的方法。有,编译通过,没有编译失败。
运行时期:参考的是对象所属的类中是否有调用的方法,如果有运行子类自己的方法,如果没有就父类的方法。
简答说:编译时期看左边,运行时期看右边。
因为函数有一个覆盖的特性。
非静态方法需要和当期运行的对象进行动态绑定,哪个对象调用了这个方法,这个方法就所属于哪个对象。
就会运行哪个对象的中的方法。
3,静态函数。
编译时期:参考的是引用型变量所属的类中是否该方法。
运行时期:参考的也是引用型变量所属的类中的方法。
简单说:编译和运行都看左边。
因为静态方法是不所属于对象的,是所属于类的,
它会类加载的时候,静态的绑定到所属的类上。
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/)
黑马程序员IT技术论坛 X3.2