Java短期班day06

一、构造方法

 构造方法的作用: 在创建对象的时候,给对象的成员变量赋予初值

   构造方法的的语法:
   1. 构造方法也是一种方法,定义语法和成员有相似之处
   2. 但是,和普通成员方法定义语法,又去被
      a. 构造方法的方法名固定,和类名相同
      b. 构造方法没有返回值,定义的时候没有返回值类型

  构造方法的工作原理:
  1. 在new对象的时候,给构造方法传递参数值
  2. 构造方法在运行的时候,接受外部传递的参数值
  3. 在构造方法的方法体中,根据我们自己定义好的赋值语句,
     完成对对象成员变量值的初始化(给对象的成员变量赋初值)

 注意事项:
1) 构造方法可以重载(也要满足方法的重载条件)

2) 当一个类中,没有定义任何一个构造方法的时候,jvm会自动给我们的类中,
   添加一个默认构造(无参构造方法)方法,但是如果一个类中,一旦定义了哪怕只有一个构造方法
   ,此时jvm就不会自动给该类添加默认构造方法(无参构造方法)

3) 关于构造方法的执行时机,构造方法,在创建对象的最后一步,才会执行
package com.cspratice.object01;

public class Create {

    public static void main(String[] args) {
        //构造方法静态赋初值,类似数组静态初始化
        Student student1 = new Student("李明",19,1001);

        student1.eat();
        System.out.println("name为"+student1.name + " age为" + student1.age + " num为" + student1.num);

//       //测试多个对象指向问题
//        Student student2 = new Student("五五",9,1003);
//        Student student3 = student2;
//       //由于student3指向了student2所指的地址
//        student3.name="aaa";
//        System.out.println("student2.name="+student2.name);
    }
}

class  Student {
    //成员变量
    String name;
    int age;
    int num;//学号

   //构造方法
   public Student (String name , int age , int num ) {
       this.name = name;
       this.age = age ;
       this.num = num;
   }



    public void eat() { //成员方法
        System.out.println(this.name+"在吃饭");
    }




}

二、代码块

代码块: 在Java中,使用{}括起来的代码被称为代码块,根据其位置和声明的不同
       可以分为局部代码块,构造代码块,静态代码块,同步代码块(多线程讲解)

   对于每种代码块,需要重点掌握,定义位置和声明方法 执行时机

   1)局部代码块(知道)
      定义:  方法体中定义的代码块
      执行时机:  随着方法的执行而执行
      作用:限定变量生命周期,及早释放,提高内存利用率(扯淡, 带来的内存利用率的优化可以忽略不计)
           从代码的可读性的角度,不推荐大家从内存利用率的角度使用局部代码块

      在嵌套的作用域中,不能定义同名局部变量,在没有嵌套关系的不同的代码块中,可以定义同名变量

    2) 构造代码块(初始化代码块)
      定义: 定义在类中方法体之外
      执行时机: 创建对象的时候执行, 并且每次创建对象都会执行
      作用:
        1.多个构造方法方法中相同的代码可以放在构造代码快,每次创建对象都会执行
        2.如果有代码,在每次创建对象时都执行,并且构造方法前执行

        构造方法 VS 构造代码块 构造代码块优先于构造方法执行
        从给对象成员变量初始化的角度,总结一下,有三种方式在创建对象的过程种,给对象的成员变量赋初值
        1. 构造方法
        2. 构造代码块
        3. 成员变量的初始化语句

        构造代码块 优先于 构造方法执行
        成员变量的初始化语句 优先于 构造方法执行
        构造代码块 VS 初始化语句:
           a.它们并没有固定的先后顺序,按照代码书写的先后来决定,谁在前先执行谁
           b.但是习惯上,我们会把成员变量的初始化语句写在构造代码块之前,所以通常
             初始化语句优先于构造代码块执行


        3) 静态代码块
        定义:  定义在类种方法体之外,被static修饰
        执行时机:随着类加载而执行,因为一个类的加载正常情况下在一个jvm只会发生一次
                  静态代码块,在一个jvm中最多执行一次

        作用: 有些场景下,有些代码我们仅仅只需要执行一次,这种代码可以放在静态代码块中执行
        注意事项:
           静态代码块也属于静态上下文的一种
package com.cspratice.block;

public class Block {

    public static void main(String[] args) {

        // 创建对象
        BlockClass first = new BlockClass();
        System.out.println(first.memberField);

        //BlockClass second = new BlockClass();
    }



}


class BlockClass {

    // 成员变量的初始化语句
    int memberField = 2000;

    // 构造代码块
    {
        memberField = 100;
        System.out.println("init code block");
    }

    // static context
    // 静态代码块
    static  {

        // 不能访问非静态的成员变量
        //System.out.println(memberField);

        // 不能访问非静态成员方法
        //localMethod();

        System.out.println("static code block");
    }





    public BlockClass() { //构造方法
        // 一段代码
        memberField = 1000;
        System.out.println("BlockClass");
    }



    public void localMethod() {
        int b = 10;
        // 局部代码块
        {
            // 只要执行完了变量的作用域,变量的存储空间就会被回收
            int a = 10;
            System.out.println(a);
            System.out.println(b);


            // 在嵌套的作用域中,不能定义同名局部变量
            //int b = 90;
        }


        {
            // 在没有嵌套关系的不同的作用域中,可以定义同名局部变量
            int a = 100;
            System.out.println(a);

        }
        // 在变量声明的作用域之外
        //System.out.println(a);

    }

}

三、导包语句

在Java源程序文件的第一行使用package声明,该文件中定义的类所属的包
java中如何唯一确定一个类? 类的全限定名唯一区分一个类

在类名前面加上类所属的包名,中间用句点“.”分隔,称为类的完全限定名(Full Qualified Name),
简称类的限定名,或全限定名

 com.cskaoyan.object01.syntax.keyimport.A
 com.cskaoyan.object01.syntax.keyimport.anotherpackage.A


 当在类体中使用了与当前类不同包的类名时,编译器编译时因为无法找到该类的定义而失败,
 有两个解决办法:
   1.使用不同包类的完全限定名
   2.使用import声明,为编译器提供该类的定义信息

import注意事项
   1. import声明一般紧跟在package声明之后,必须在类声明之前,其基本语法如下:
            import <类的完全限定名>;

   2.Java语言核心包java.lang包中的类将被隐式导入,可以直接使用其中的类

   3.import声明提供了一种包的智能导入方式:
      import <包名>.*;
         a. 包中的类将根据需要导入,避免使用多条import声明
         b. 智能导报语句, 不会递归导入子包中的类

四、Static

 static关键字:可以修饰成员变量和成员方法
       被static修饰成员变量,称之为静态成员变量,简称静态变量
       被static修饰的成员方法,称之为静态成员方法,简称静态方法


   1. 被当前类的所有 对象所共享(共享特征):(判定是否使用static的关键, 这里就说明static的使用场景)
      a. 当static修饰了成员变量,该成员变量的值,就不在存储于对象中了,
          而是,单独存储了一份,被类的所有对象所共享

      b.  当static修饰成员方法的时候,该方法被当前类的所有对象共享
          当前类对象.方法(和普通成员方法从共享的角度,几乎没有太大区别)

  2. 可以通过类名访问(对于静态成员,官方推荐类名.访问静态成员)
      a. 可以通过类名直接访问,static成员变量的值
      b. 直接通过类名直接调用,static成员方法

3. 随着类的加载而加载(出现在内存中的时间)
    a. static成员变量,随着类加载过程,其实就已经在方法区中,分配了内存,并赋予默认初值
    b. static成员方法, 一旦类加载完毕,我们就可以直接访问,static方法(通过类名.),而不必等待创建该类对象

4. 优先于对象而存在(不依赖于对象而存在)

    a. 静态变量
        1)成员变量的角度来理解,static修饰的成员变量,不在依赖于对象而存在,因为static修饰的成员变量的值,
          不在存储在,该类的每个对象中
        2)作为对比,没有被static修饰的成员变量,都依赖于对象而存在,因为他们的值,都存储在对象中

    b. 静态方法
        1)成员方法角度,被static修饰的成员方法,在没有对象存在的情况下,也可以直接通过类名来调用方法
        2)作为对比,没有被static修饰的,普通成员方法,它依赖于对象而存在


    static关键字的注意事项:
       1. 在静态上下文中(比如静态方法中),不能访问非静态的成员变量或者非静态的成员方法
          a. 这里,实际上不能访问的是 当前对象 的非静态成员变量和非静态成员方法
          b. 如果我们是在自己创建出的已经存在的对象上访问非静态的成员变量和成员方法是可以的

       2. static方法体中不能使用static关键字

       3. 静态变量和静态方法的使用场景
         a. 如果我们希望一个成员变量,能够被该类的所有对象所共享,该变量可以定义
            static 静态变量
         b. 如果说一个方法,该方法作为一个工具方法实现,为了方便调用,我们可以把这种
            被频繁调用工具方法,定义static 方法

静态成员变量和普通成员变量:

静态成员变量和普通成员变量:
所属不同
    静态变量属于类,所以也称为为类变量
    成员变量属于对象,所以也称为实例变量(对象变量)
内存中的位置不同
    静态变量存储于方法区
    成员变量存储于堆内存
内存出现时间不同
    静态变量随着类的加载而加载,随着类的消失而消失
    成员变量随着对象的创建而存在,随着对象的消失而消失
调用不同
    静态变量可以通过类名调用,也可以通过对象调用
    成员变量只能通过对象名调用
public class Demo2Static {

    public static void main(String[] args) {

        // 被static修饰的成员 类名.的方式访问
//        System.out.println(StaticClass.a);
//        StaticClass.staticMethod();

        // 被static修饰成员变量和成员方法,对象.方式访问
//        StaticClass obj = new StaticClass();
//        System.out.println(obj.a);
//        obj.staticMethod();

        // 随着类加载而加载
        // 不创建任何对象,直接通过类名来访问
        //StaticClass.a = 1000;
        //System.out.println(StaticClass.a);
        // 在来加载完就可以访问了
        //StaticClass.staticMethod();

        // 不依赖与对象而存在
        //StaticClass staticClass = new StaticClass();
        // 普通成员方法
        //staticClass.memberMethod();

        // 静态方法
        StaticClass.staticMethod();
    }
}


class StaticClass {
    // 静态成员变量
    static int a;

    // 普通成员变量
    double b;

    public static void staticMethod() {
        // 静态方法中,访问非静态的成员变量
        //System.out.println(this.b);

        // 静态方法中,访问非静态的成员方法
        //this.memberMethod();

//        // 自己创建出的对象上
        StaticClass obj = new StaticClass();
        // 非静态的成员变量
        System.out.println(obj.b);

        // 非静态的成员方法
        obj.memberMethod();


        System.out.println("staticMethod");

        // 在方法体中定义不能使用static
         //static int value;
    }

    public void memberMethod() {
        // 普通成员变量值
        System.out.println(this.b);
        System.out.println("memberMethod");


        //static int a;

        // 可以访问静态变量和静态方法
        System.out.println(a);
        staticMethod();
    }
}

五、this

  this: 代表对象自身的引用(表示当前对象的引用)

  this关键字:代表当前对象的引用
 1. 当this出现在构造方法的方法体中的时候
    因为构造方法执行的时候,正在创建对象,this表示当前构造方法执行时,正在创建的那个对象

 2. 当this出现在普通成员方法中的时候
    a. 对于一个普通成员,我们只能通过 对象名. 访问成员方法
    b. 在哪个对象上,访问普通成员方法,this所表示的当前对象,就是哪个对象

this关键字的作用:
   1.解决成员变量的隐藏的问题
   2.访问对象的成员(成员变量 和 成员方法)
   3.访问对象的构造方法
     a. 语法this(实际参数列表)调用到和实际参数列表相匹配的构造方法
     b. this 调用构造方法不能出现在普通方法的方法体中
     c. this 调用构造方法,只能出现在构造方法的方法体,第一条语句
public class Student {

    String name;

    int age;

    int studentId;

    /*
         自己定义无参默认构造方法
         我希望利用默认构造方法创建出的对象,各个成员变量值,不是默认初值
          而是希望,它们的默认初始是
          name      "未知"
          age         -1
          studentId  -1
      */
    public Student() {
//        name = "未知";
//        age = -1;
//        studentId = -1;

        // 调用三参构造方法
        // System.out.println();
        this("未知", -1, -1);
    }

    // 构造方法的重载
    public Student(String stuName) {
        name = stuName;
    }

    // 定义构造方法
    public Student(String name, int age, int studentId) {
        // lisi--20--2
        //System.out.println(name + "--" + age + "--" + studentId);
        // 利用this解决成员变量的隐藏
        this.name = name;
        this.age = age;
        this.studentId = studentId;
    }

    // 对象名.callConstructor()
    public void callConstructor() {
        // 利用this对构造方法的调用,不能出现在普通方法的方法体中
        //this("未知", -1, -1);
    }

    public void eat() {
        // 普通成员方法中
        System.out.println(this.name);
        System.out.println("吃饭ing");

        //  这里的name相当于this.name 简化写法,前提是没有定义同名成员变量
        System.out.println(name);
    }

    public void test() {
        // 通过this访问当前对象的成员方法
        this.eat();
        // 这里相当于this.eat()的简化写法
        eat();
    }

}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值