在看Java开发实战经典的时候看到覆写一部分,大致代码如下:
public class Hello
{
public static void main(String[] args)
{
new Student().fun();
}
}
class Person
{
private void print()
{
System.out.println("Person");
}
void fun()
{
this.print();
}
}
class Student extends Person
{
public void print()
{
System.out.println("Student");
}
}
这时候子类Student的print不算覆写了父类Person的print,这时候fun()调用的是父类的print输出”Person"。但是一旦去掉父类print的private访问权限,使得子类的print覆写了父类的print,这时候就调用了子类的print输出”Student“了。
这一块内容我作为初学者表示很难理解:
如果父类的print有private访问权限,我可以这么理解,new Student().fun()在子类中没找到fun(),然后到父类中找到了,这时候this指向父类,所以this.print()调用的是父类的print()从而输出了“Person"。但是这种理解在去掉private访问权限后的情况中又说不通了。
如果父类的print没有private访问权限,我可以这么理解,子类继承了父类的fun(),所以调用Student().fun()就直接调用了子类的fun(),这时候this指向子类,所以直接调了子类的print()输出”Student"。但是这样理解在private访问权限有的情况下又说不通了。
有没有大神能解释一下这两种情况怎么理解啊?我百度了一下有说是动态绑定的原因,但是我稍微看了下也没有把动态绑定讲清楚的。还是理解不能啊。
你好,我是这么理解的。
首先要知道,父类中的private变量和方法无法被子类继承,当然也不能被子类见到。
所以,加了private,还是调用父类的方法;相反,不加private,就是default默认的权限,子类可以继承,所以当前对象的print()就输出Student
希望可以帮到你!
复写 是这个吧 没记错的话!
重写(Overriding)
(1) 父类与子类之间的多态性,对父类的函数进行重新定义。如果在子类中定义某方法与其父类有相同的名称和参数,我们说该方法被重写 (Overriding)。在Java中,子类可继承父类中的方法,而不需要重新编写相同的方法。
但有时子类并不想原封不动地继承父类的方法,而是想作一定的修改,这就需要采用方法的重写。
方法重写又称方法覆盖。
(2)若子类中的方法与父类中的某一方法具有相同的方法名、返回类型和参数表,则新方法将覆盖原有的方法。
如需父类中原有的方法,可使用super关键字,该关键字引用了当前类的父类。
(3)子类函数的访问修饰权限不能少于父类的;
下面是重写的例子:
概念:即调用对象方法的机制。
动态绑定的内幕:
1、编译器检查对象声明的类型和方法名,从而获取所有候选方法。试着把上例Base类的test注释掉,这时再编译就无法通过。
2、重载决策:编译器检查方法调用的参数类型,从上述候选方法选出唯一的那一个(其间会有隐含类型转化)。
如果编译器找到多于一个或者没找到,此时编译器就会报错。试着把上例Base类的test(byte b)注释掉,这时运行结果是1 1。
3、若方法类型为priavte static final ,java采用静态编译,编译器会准确知道该调用哪
个方法。
4、当程序运行并且使用动态绑定来调用一个方法时,那么虚拟机必须调用对象的实际类型相匹配的方法版本。
在例子中,b所指向的实际类型是TestOverriding,所以b.test(0)调用子类的test。
但是,子类并没有重写test(byte b),所以b.test((byte)0)调用的是父类的test(byte b)。
如果把父类的(byte b)注释掉,则通过第二步隐含类型转化为int,最终调用的是子类的test(int i)。
http://blog.csdn.net/lovelion/article/details/7540445
http://www.cnblogs.com/cbf4life/archive/2009/12/11/1622245.html