方法的重载:

方法的重载:对返回值不要求;对访问权限也不要求;要求方法名相同,要求参数签名不同

在扎瓦中,同一个类中,不能出现方法名相同,参数签名(参数的类型,参数个数,参数顺序)也相同的方法。(编译会出错)

public Person(){}
public void Person(){}

编译可以通String

过,原因:调用的主体不同,第一个构造方法是JVM调用,第二个是对象调用的实体方法。

重载的方法谁来识别?

编译器识别。重载就是在编译的时候就可以识别调用那个构造方法,但是只有在执行的时候才知道给哪些变量赋值。

所以重载又叫做:静态多态,编译多态,静态联编。

抽象方法可以重载,也可以重载成非抽象方法。

主方法也可以重载,虚拟机先找main,发现一样,之后再次找参数签名类型为String[]类型的主方法。(但是一般不用,主要是0用0来应付面试)

主要用在:构造方法还有println中。

方法的重写(override):

子类对父类的方法(实例方法)做了重写,子类覆盖了父类的方法,就不会再和父类动态绑定了。

前提:

  1. 发生在两个类中;
  2. 这两个类一定要继承关系。
  3. 覆盖的方法一定要被子类继承。(所以父类的私有方法不能被覆盖)
  4. 声明为 final 的方法不能被重写。
  5. 声明为 static 的方法不能被重写,但是能够被再次声明。

条件:

  1. 方法名相同。
  2. 参数签名要相同。
  3. 返回值相同。
  4. 访问权限一定要比父类松。(访问权限排序:private,默认,protected,public)。
  5. 子类想要覆盖父类的方法子类不能声明抛出比父类更多的异常。(详情在异常那边)

用处:

主要用在对抽象方法的重写。

实例方法的重写(叫覆盖)。

主方法不能被覆盖,也不可以被继承。

子类对父类的静态方法重写(叫隐藏):

父类变量指向子类对象:

即使子类对父类当中的静态方法进行重写(必须使用静态方法进行重写)了,就是重新在方法区里的静态数据区开辟了一块空间,在对象的堆里有这块空间的引用,也就是说这个方法是子类自己新增加的方法,父类变量看不到,使用的依然是父类的静态方法(通过动态绑定进行查找)。(这就是隐藏)。

造型:

  造型分为两种:

   ①:向上造型或自动类型转换,如int变为double。

    ②:向下造型或强制类型转换,如double变为int。

  1. 造型只是对变量里的内容改变类型,对变量本身类型没有改变。
int a;
double b=9.99;
a=(int) b;

b的类型不变,变的只是9.99, 9.99变成了9.

super关键字:

return super.showName();//表明调用的showName()是和父类做动态绑定的,而且还会把子类对象的地址传给和父类做动态绑定的showName()。

在Java类中使用super来引用父类的成分

1,super可用于访问父类中定义的属性

2,super可用于调用父类中定义的成员方法

3,super可用于在子类构造器中调用父类的构造器

4,super的追溯不仅于直接父类

this关键字在构造方法里的含义:(主要就是调用本类的构造器)

初始化块(在类中):

直接在类里面初始化,不用构造方法初始化。

调用的时机决定于初始化块的位置。当初始化块中用到没有定义的的属性或者方法时(极限:直接把初始化块放在类中的最前面),就会报错。

但是不管初始化块放在哪里,他一定会比构造方法执行的早。所以一般把初始化块放在类里的最后一行。

子类初始化块可以给从父类继承的属性初始化。

  初始化块和构造方法的执行顺序以及构造方法的压栈和弹栈:

Teacher类:

java私有方法aop java私有方法不能被重载_私有方法不能被子类覆盖

Person类:

java私有方法aop java私有方法不能被重载_构造方法_02

t1测试类:

java私有方法aop java私有方法不能被重载_私有方法不能被子类覆盖_03

t1内存图(重):

java私有方法aop java私有方法不能被重载_父类_04

t3测试类:

java私有方法aop java私有方法不能被重载_父类_05

t3内存图(重):

java私有方法aop java私有方法不能被重载_子类_06

Person t2 = new Teacher("Tom");压栈过程:

    创建对象的时候进行首先压栈。           

//这个时候jvm并不知道到底调用哪一个构造方法
 //,于是先把当前这个构造方法压入栈中去,之后再看这个子类构造方法里面的情况;
 //1,有一个this,this里面有n个参数,就接着把子类中有n个参数的构造方法压栈。
 //2,有一个super,super里面有n个参数,纠结着把父类中有n个参数的构造方法压栈。之后再继续压栈,直到没有构造方法了。压栈结束
 //3,既没有this,又没有super,如果这个构造方法是在子类中的,于是就去父类中把父类无参的构造方法压入栈中,之后再继续压栈,直到没有构造方法了。压栈结束。
 //4,既有this,又有super,报错。this和super不能同时出现在一个构造方法中。

弹栈过程:

  1. 压完栈之后,开始创建子类对象,首先创建继承父类的属性,为继承父类的属性开辟完空间之后。
  2. 父类初始化块开始为属性初始化。
  3. 接着,父类构造方法开始给这些属性进行初始化。弹栈开始,栈的后进先出机制,后面进栈的构造方法一个个弹栈给父类属性进行初始化。
  4. 完了之后。接着给自己新增加的属性开辟空间。
  5. 子类初始化块开始为属性初始化。
  6. 接着子类构造方法开始给这些属性进行初始化,弹栈再一次开始,栈的后进先出机制,后面进栈的构造方法一个个弹栈给子类新增加的属性进行初始化。
  7. 完了之后,弹栈结束。

最后:各种初始化快以及构造器的执行顺序:

父类静态初始化块
            子类静态初始化块
            父类初始化块
            父类构造器
            子类初始化块
            子类构造器