第十章:面向对象编程(高级部分)(上)

                                                目录

10.1类变量(静态变量)类方法

10.2类变量的内存布局

10.3如何访问类变量

10.4类变量使用注意事项和细节讨论

10.5 类方法(static静态方法)   

10.6类方法的使用场景

10.7 类方法使用细节

10.8深入理解mian方法(public static void main(String [] args){}

10.9 代码块

10.10代码块注意事项

10.11代码块的用处及案例演示

3、案例演示

10.12代码块的注意事项和使用细节

2.类什么时候被加载呢?(重点)

10.13创建对象时,在一个类中的调用顺序(重点)

10.14 创建一个子类对象时,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下


10.1类变量(静态变量)类方法

  1. 静态变量最大的特点就是会被其所在类中的所有对象实例共享(private static int n1 = 10;)
  2. 访问类变量:类名.类变量名
  3. 类变量是随着类的加载而创建,所以即使没有创建对象实例也可以访问
  4. 类变量的访问也必须遵守访问权限

10.2类变量的内存布局

这里需要注意的是static变量的位置跟jdk的版本有关,有的说是在方法区有的说是在静态域。

不管她在哪我们需要记住以下两点

1、static变量是同一个类所有对象共享

2、static类变量在类加载的时候就生成了

10.3如何访问类变量

1、访问类变量:类名.类变量名 or 对象名.类变量名

2、注意:静态变量的访问修饰符和访问范围权限和普通变量是一样的

10.4类变量使用注意事项和细节讨论

  1. 什么时候需要使用类变量

当我们需要让某个类的所有对象共用一个变量时,可以将该变量设置成静态变量

2、加上static 称为类变量或者静态变量否则称为 普通变量/实例变量/非静态变量

3、访问类变量:类名.类变量名 or 对象名.类变量名(java设计者推荐我们使用类名.类变量名)

4、类变量在类加载时就初始化了,就是说即使没有创建对象,只要类加载了就可以使用类变量

10.5 类方法(static静态方法)   

  1. public static void infor(){} //访问修饰符 static 数据返回类型 方法名(){}

  2. 同样得满足访问权限
  3. 开发自己的工具类时,可以将方法做成静态的,方便调用

10.6类方法的使用场景

1、当方法中不涉及任何和对象相关的成员,则可以将方法设计成静态方法,提高开发效率

10.7 类方法使用细节

  1. 类方法和普通方法都是随着类的加载而加载,将结构信息储存在方法区,类方法中无this、super的参数,不能使用this,super。 普通方法中隐含着this参数,this和super都可以使用
  2. 类方法可以通过类名调用,同样也可以通过对象名调用
  3. 类方法(静态方法)只能调用静态成员(静态属性、静态方法)

  4. 普通方法既可以调用静态成员(静态属性、静态方法)也可以调用普通成员(普通属性、普通方法)

10.8深入理解mian方法(public static void main(String [] args){}

  1. main方法是谁调用的呢?答:虚拟机调用
  2. java虚拟机要调用类的main()方法,所以该方法的访问权限必须时public
  3. java虚拟机在执行main()方法不必时不必创建对象,所以该方法必须是static
  4. 该方法接收的时String类型的数组参数,该数组中保存执行java命令时传递给所运行的类的参数
  5. 提示:在main‘方法中我们可以直接调用main方法所在类的静态属性
  6. 但是不能直接调用非静态属性,必需实例化对象后才能通过对象调用

10.9 代码块

1.基本介绍:代码块属于类中的成员(是类的一部分)类似于方法,将逻辑语言封装到方法体中,通过{}包围起来。

2、和方法不同,没有方法名,没有返回,没有参数,只有方法体,并且不用通过对象调用,而是在类加载的时候或者创建对象时隐式调用。

3、语法 修饰符{

        代码

}

10.10代码块注意事项

1、修饰符要是写的话只能写static

2、代码块分为两类,使用static修饰的代码块,叫做静态代码块,否则称为普通代码块

3、代码块中的逻辑语句可以为任意的逻辑语句

5、;可以写,也可以省略

10.11代码块的用处及案例演示

1、我的理解:代码块相当于另一种形式的构造器(对构造器的补充机制),可以做初始化的操作

2、使用场景:如果多个构造器中都含有重复的语句,可以抽取到初始代码块中,提高代码的重用性

3、案例演示

package com.cds.block;

public class Test01 {
    public static void main(String[] args) {
        Movie movie = new Movie("泰坦尼克号");
        System.out.println("================================");
        Movie movie1 = new Movie("泰坦尼克号",39);
        System.out.println("================================");
        Movie movie2 = new Movie("泰坦尼克号",39,"jack");
    }
}
class Movie{
    private String name;
    private double price;
    private String director;

     {
        System.out.println("电影屏幕打开...");
        System.out.println("广告开始...");
        System.out.println("电影正是开始...");
    }


    /*
    * (1) 下面的三个构造器都有相同的语句
    * (2)这样代码看起来比较冗余
    * (3) 这时我们可以把相同的语句,放入到一个代码块中,即可
    *(4) 这样当我们不管调用哪个构造器,创建对象,都会先调用代码块的内容
    * (5)代码块调用的顺序优先于构造器.
     */


    public Movie(String name) {
//        System.out.println("电影屏幕打开...");
//        System.out.println("广告开始...");
//        System.out.println("电影正是开始...");
        this.name = name;
    }

    public Movie(String name, double price) {
//        System.out.println("电影屏幕打开...");
//        System.out.println("广告开始...");
//        System.out.println("电影正是开始...");
        this.name = name;
        this.price = price;
    }

    public Movie(String name, double price, String director) {
//        System.out.println("电影屏幕打开...");
//        System.out.println("广告开始...");
//        System.out.println("电影正是开始...");
        this.name = name;
        this.price = price;
        this.director = director;
    }
}

10.12代码块的注意事项和使用细节

1、static代码块也叫静态代码块,静态代码块时随着类的加载被执行,且只会执行一次,而普通代码块 每创建一个对象就被调用

2.类什么时候被加载呢?(重点)

  1. 创建对象实例时(new)
  2. 创建子类对象实例时,父类也会被加载
  3. 使用类的静态成员时(静态属性,静态方法)

案例演示

//创建对象实例时(new),静态代码块和普通代码块都执行,且静态优先,因为先加载类

第十章:面向对象编程(高级部分)(上)_第1张图片

//使用类的静态成员时(静态属性,静态方法),类加载,静态代码块执行

第十章:面向对象编程(高级部分)(上)_第2张图片

//当创建子类对象时,先调用父类的静态代码块,再子类静态代码块,再父类普通代码块,再子类普通代码块。

第十章:面向对象编程(高级部分)(上)_第3张图片

 源码:

package com.cds.block;
/*
* 1、static代码块也叫静态代码块,静态代码块时随着类的加载被执行,
* 且只会执行一次,而普通代码块 每创建一个对象就被调用
2.类什么时候被加载呢?(重点)
创建对象实例时(new)
创建子类对象实例时,父类也会被加载
使用类的静态成员时(静态属性,静态方法)*/
public class Test02 {
    public static void main(String[] args) {
//        System.out.println(A.age);//使用类的静态成员时(静态属性,静态方法),类加载
//        A a = new A();//创建对象实例时(new),静态代码块和普通代码块都执行,且静态优先,因为先加载类
        B b = new B();
    }
}
class A{
    public static int age = 100;
    public static void say(){
        System.out.println("A类中say()静态方法执行");
    }
    static {
        System.out.println("A类的静态代码块执行");
    }
    {
        System.out.println("A类的普通代码块被执行");
    }

}
class  B extends A{
    static {
        System.out.println("B类的静态代码块执行");
    }
    {
        System.out.println("B类的普通代码块被执行");
    }
}

10.13创建对象时,在一个类中的调用顺序(重点)

(1)调用静态代码块和静态属性初始化(注意静态代码块和静态属性的优先级是一样的如果有多个静态代码块和静态属性则按照他们的顺序执行)

(2)调用普通代码块和普通属性(注意普通代码块和普通属性的优先级是一样的如果有多个普通代码块和普通属性则按照他们的顺序执行)

案例演示

第十章:面向对象编程(高级部分)(上)_第4张图片

 源码:

package com.cds.block;


/*
* (1)调用静态代码块和静态属性初始化
* (注意静态代码块和静态属性的优先级是一样的
* 如果有多个静态代码块和静态属性则按照他们的顺序执行)

(2)调用普通代码块和普通属性
* (注意普通代码块和普通属性的优先级是一样的
* 如果有多个普通代码块和普通属性则按照他们的顺序执行)*/
public class Test03 {
    public static void main(String[] args) {
        AA aa = new AA(19);
    }
}
class AA{
    private static int age = getAge();
    static {
        System.out.println("AA类中静态代码块被执行");
    }

    public  static int getAge(){
        System.out.println("AA类中getAge()被调用,静态变量初始化");
        return 100;
    }

    public AA(int age) {
        System.out.println("AA类中构造器被调用");
        this.age = 10;
    }

    public static void say(){
        System.out.println("AA类中静态方法say()被执行");
    }

    public void hello(){
        System.out.println("AA类中普通方法hello()被执行");
    }
    private int n2 = getN2();
    public int getN2(){
        System.out.println("AA类中getN2()被调用,普通变量初始化");
        return 200;
    }
    {
        System.out.println("AA类中普通代码块被执行");
    }

}
class BB {

}

 (3)构造器 的前面 其实是隐藏了(1) super()和(2)调用普通代码块,!!!!重要

就是·静态代码块是加载类时直接执行,然后普通代码块在创建对象时,是在构造器中隐藏的super()后面执行的。

静态相关的·代码块,属性初始化,在类加载时,就执行完毕,因此是优先于构造器和普通代码块和普通代码块执行的

案例演示:

 

第十章:面向对象编程(高级部分)(上)_第5张图片

源码:

package com.cds.block;
/*
 * 构造器 的前面 其实是隐藏了 super()和调用普通代码块,
 * 静态相关的·代码块,属性初始化,在类加载时,就执行完毕,
 * 因此是优先于构造器和普通代码块和普通代码块执行的*/
public class Test04 {
    public static void main(String[] args) {
        BBB bbb = new BBB();
    }
}
class AAA{
    {
        System.out.println("AAA的普通代码块被调用");
    }

    public AAA() {
        System.out.println("AAA的构造器被调用");
    }
}
class BBB extends AAA{
    {
        System.out.println("BBB的普通代码块被调用");
    }

    public BBB() {
        //这里有隐藏的执行要求
        //(1)super()
        //(2)调用普通代码块
        System.out.println("BBB的构造器被调用");
    }
}

10.14 创建一个子类对象时,他们的静态代码块,静态属性初始化,普通代码块,普通属性初始化,构造方法的调用顺序如下

  1. 类的静态代码块 \类的静态属性初始化(二者优先级一样,按照定义顺序执行)
  2. 类的静态代码块 \类的静态属性初始化(二者优先级一样,按照定义顺序执行)
  3. 类的普通代码块和普通属性初始化 (二者优先级一样,按照定义顺序执行)
  4. 类的构造方法
  5. 类的普通代码块和普通属性初始化 (二者优先级一样,按照定义顺序执行)
  6. 类的构造方法

注意:静态代码块只能直接调用静态成员(静态 属性和静态方法),普通代码块可以调用任意成员。

第十章:面向对象编程(高级部分)(上)_第6张图片

源码:

package com.cds.block;


import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer;

/*
* (1)调用静态代码块和静态属性初始化
* (注意静态代码块和静态属性的优先级是一样的
* 如果有多个静态代码块和静态属性则按照他们的顺序执行)

(2)调用普通代码块和普通属性
* (注意普通代码块和普通属性的优先级是一样的
* 如果有多个普通代码块和普通属性则按照他们的顺序执行)*/
public class Test03 {
    public static void main(String[] args) {
        BB bb = new BB(18);
    }
}


class AA{
    private static int age = getAge();
    static {
        System.out.println("AA类中静态代码块被执行");
        System.out.println(AA.age);//静态代码块里面只能调用静态成员
        AA.say();//静态代码块里面只能调用静态成员
//        AA.n2;//静态代码块里面不能调用普通成员
    }

    public  static int getAge(){
        System.out.println("AA类中getAge()被调用,静态变量初始化");
        return 100;
    }

    public AA(int age) {//构造器

        System.out.println("AA类中构造器被调用");
        this.age = 10;
    }

    public static void say(){
        System.out.println("AA类中静态方法say()被执行");
    }

    public void hello(){
        System.out.println("AA类中普通方法hello()被执行");
    }
    private int n2 = getN2();
    public int getN2(){
        System.out.println("AA类中getN2()被调用,普通变量初始化");
        return 200;
    }
    {
        System.out.println("AA类中普通代码块被执行");
    }

}
class BB extends AA{
    private static int num1 = getNum1();
    private int num2  = getNum2();

    public int getNum2() {
        System.out.println("BB类的普通属性初始化");
        return 400;
    }

    public static int getNum1() {
        System.out.println("BB类的静态属性初始化");
        return 300;
    }

    static {
        System.out.println("BB类的静态代码块被调用");
    }
    {
        System.out.println("BB类的普通代码块被执行");
    }
    public BB(int age) {
        super(age);
        System.out.println("BB类的构造器被执行");
    }

}





好啦,上篇就到这里了~

马上更新下篇哦。

你可能感兴趣的:(java,开发语言)