Java-类初始化
类初始化过程
(1)一个类要创建实例需要先加载并初始化该类
main方法所在的类需要先加载和初始化
(2)一个子类要初始化需要先初始化父类
(3)一个类初始化就是执行 < clinit>()方法
< clinit>()方法由静态类变量显示赋值代码和静态代码块组成
类变量显示赋值代码和静态代码块代码从上到下顺序执行
< clinit>()方法只执行一次。
实例初始化过程
(1)实例初始化就是执行()方法
< init>()方法可能重载有多个
有几个构造器就有几个< init>方法
< init>()方法由非静态实例变量显示赋值代码和非静态代码块、对应构造器代码组成
(2)非静态实例变量显示赋值代码和非静态代码块代码从上到下顺序执行,而对应构造器的代码最后执行
(3)每次创建实例对象,调用对应构造器,执行的就是对应的< init>方法
(4)< init>方法的首行是 super()或super(实参列表),即对应父类的< init>方法
类加载
类加载的过程:
(1)类的装载 - 将类的字节码文件加载到JVM方法区中
(2)类的连接 - 对类的静态属性赋予默认值
(3)类的初始化 - 对类的静态属性手动赋值(1、直接赋值 2、静态代码块 从上到下)
实例
public class Father {
private int i = test();
private static int j = method();
static {
System.out.print(" " + 1 + " ");
}
Father() {
System.out.print(" " + 2 + " ");
}
{
System.out.print(" " + 3 + " ");
}
public int test() {
System.out.print(" " + 4 + " ");
return 1;
}
public static int method() {
System.out.print(" " + 5 + " ");
return 1;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Father father = new Father();
}
}
运行结果
子类继承父类
public class Son extends Father {
private int i = test();
private static int j = method();
static {
System.out.print(" " + 6 + " ");
}
Son() {
System.out.print(" " + 7 + " ");
}
{
System.out.print(" " + 8 + " ");
}
public int test() {
System.out.print(" " + 9 + " ");
return 1;
}
public static int method() {
System.out.print(" " + 10 + " ");
return 1;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s1 = new Son();
System.out.println();
System.out.println("===================");
Son s2 = new Son();
}
}
运行结果
方法的重写Override
重写(Override):运行时多态,如果一个子类继承了一个父类,子类中拥有和父类相同方法名称,返回值,参数类型的话,就是重写,会执行子类中的方法。
但要注意子类函数的访问修饰权限不能少于父类(public>protected>default>private)。
重写方法一定不能抛出新的检查异常或者比被重写方法申明更加宽泛的检查型异常
Override重写的要求?
(1)方法名
(2)形参列表
(3)返回值类型
(4)抛出的异常列表
(5)修饰符
哪些方法不可以被重写
(1)final方法
(2)静态方法
(3)private等子类中不可见方法
案例
class Father{
public void Hello() {
System.out.println("Father say hello");
}
}
public class Son extends Father{
@Override
public void Hello() {
System.out.println("Son say hello");
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Son s1 = new Son();
s1.Hello();
}
}
对象的多态性
(1)子类如果重写了父类的方法,通过子类对象调用的一定是子类重写过的代码
(2)非静态方法默认的调用对象是this
(3)this对象在构造器或者说方法中就是正在创建的对象
方法的重载Overloading
重载(overloading):编译时多态, 在一个类里面,方法名字相同,而参数不同。返回类型可以相同也可以不同。
案例
public class A {
public static void Eat() {
System.out.println("A在吃饭!");
}
public static void Eat(String str) {
System.out.println(str + " 在吃饭!");
}
public static void Eat(String str, Date date) {
System.out.println(str + " 在 " + date + " 吃饭!");
}
}
重载(Overload)和重写(Override)的区别?
答:方法的重载和重写都是实现多态的方式,区别在于前者实现的是编译时的多态性,而后者实现的是运行时的多态性。重载发生在一个类中,同名的方法如果有不同的参数列表(参数类型不同、参数个数不同或者二者都不同)则视为重载;重写发生在子类与父类之间,重写要求子类被重写方法与父类被重写方法有相同的参数列表,有兼容的返回类型,比父类被重写方法更好访问,不能比父类被重写方法声明更多的异常(里氏代换原则)。重载对返回类型没有特殊的要求,不能根据返回类型进行区分。