向上造型 父类声明子类 是不是无法调用子类的方法 智只能用父类的 这有什么意义
2个回答
展开全部
这是逗动态绑定地,动态绑定是指在执行期间(非编译期)判断所引用对象的实际类型,根据其实际的类型调用其相应的方法。
而想实现逗动态绑定地,必须有继承、重写且父类引用指向子类对象,满足了这3条就属于逗动态绑定地,而它的好处就是像你说的那样,父类引用访问的是子类对象的方法,你看下边的例子吧:
public class A
{
public static void main(String args[])
{
A a=new B();
print(a instanceof A);
print(a instanceof B);
a.sayHello();
a=new C();
print(a instanceof A);
print(a instanceof C);
a.sayHello();
}
void sayHello()
{
print("Hello!");
}
public static void print(Object obj)
{
System.out.println(obj);
}
public static void print()
{
System.out.println();
}
}
class B extends A
{
void sayHello()
{
print("Hello,I'm B!");
}
}
class C extends A
{
void sayHello()
{
print("Hello,I'm C!");
}
}
它的输出结果是:
而不是输出的逗Hello地,从输出的2个true可以看出这里采用的就是逗父类引用指向子类对象地,你先别问为什么输出的不是逗Hello地,其实实际情况也正是我们希望输出逗Hello,I'm B地要好一些,因为我们new的是A类的子类B和C,虽然它们2个都可以直接采用a.sayHello来调用,但如果输出2个逗Hello地,那跟我们直接new一个A类的对象没什么区别。如果我们要想不管A有多少子类,都采用a.sayHello来调用(好记、易写、易改),且java没有逗动态绑定机制地,那么父类A的sayHello方法可就不好写了,得先判断是哪个子类,再调用相关子类的sayHello方法,这跟不采用继承,直接new个B和C的对象,再采用b.sayHello、c.sayHello没什么2样,那么这里的逗继承地将毫无意义,而且如果日后你你还需要加一个子类D,你还需要new个D的对象,再采用d.sayHello。
顺便,这里你应该还看到了我的父类A还自定义了一个print方法,它的参数既不是String也不是int、double,而是String类、int的包装类、double的包装类等类的父类对象Object类,所以我的sayHello方法里给print函数传递的是String类(父类Object的引用指向子类对象String类),而main方法里的print(a instanceof A)语句传递的是boolean的包装类(父类Object的引用指向子类对象Boolean类),所以这2种调用也是用了逗动态绑定地,如果不用呢看不是很多新手都希望java能像C那样直接print("Hello World")多好,那么如果不用逗动态绑定地,光是8个基本类型你就需要重写8个print函数,而且,System.out.println语句传递的参数个数也是不确定的(尽管最后都连接成1个String参数),你不用逗动态绑定地如何重写看你写不出来!
再举个例子,如果你写了一个小游戏,几十中坦克都继承于同一个父类:Tank类,然后,你想在游戏界面新建1个坦克,那你的main方法只需要统统采用类似于a.Draw()的语句去画一个坦克即可(全用父类对象的引用),而不需要先判断是哪个子类,再采用类似【case b:b.Draw();break;case c:c.Draw();break;……case n:n.Draw();break;】的语句(几十、几百个子类,你光判断语句恐怕就几百行了吧看),同样开火、移动都只需要调用a.Fire()、a.up()、a.down()、a.Left()、a.Right()即可。而且,如果日后你再想新加1个叫Tank99的子类,那么你的主方法里关于生成一辆Tank99坦克和Tank99的开火、移动等一系列语句都无需修改,你只需要写一个Tank99类,继承并重写Tank父类的方法即可(你不采用逗动态绑定地,那么主方法里的一切相关方法全部都需要修改,忘了1个地方,程序就出错了)。程序的可扩展性和健壮性很好,这就是java中逗动态绑定机制地的好处。
2017-04-19
展开全部
方法之所以能被子类覆盖就是因为有extends这个关键子 你已经继承了Person 所以他的一些属性和方法就是你的了 然而你又写了 void show()
void show() 本身就是父类传递给你的 也就是说你什么都不写 也照样可以点出这个方法 你写了这个之后 就是对方法的重写 (不知道你这一点理解不理解) 然而你其他的问题我没明白你到底是想问什么 你到底是想问子父类中构造方法的始化顺序还是什么 你能跟我说说吗
void show() 本身就是父类传递给你的 也就是说你什么都不写 也照样可以点出这个方法 你写了这个之后 就是对方法的重写 (不知道你这一点理解不理解) 然而你其他的问题我没明白你到底是想问什么 你到底是想问子父类中构造方法的始化顺序还是什么 你能跟我说说吗
已赞过
已踩过<
评论
收起
你对这个回答的评价是?
推荐律师服务:
若未解决您的问题,请您详细描述您的问题,通过百度律临进行免费专业咨询