java系列:作用域 构造器 和this

215 阅读6分钟

开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第5天,点击查看活动详情

作用域

基本使用

面向对象中,变量作用域是非常重要的知识点,相对来说不是特别好理解,要求深刻掌握变量作用域VarScope.java

public class VarScope {
    public static void main(String[] args) {

    }
}

class Cat1{

    double weight;//属性有默认值,和数组一致
//    public void hi(){
//        int num;
    //编译不通过,局部变量没有默认值,必须赋值后再使用
//        System.out.println("num = " + num);
//    }


    int age = 10;

    public void cry(){
        //局部变量一般是指在成员方法中定义的变量
        //n和name就是局部变量
        //n和name的作用域在cry方法中

        int n = 10;
        String name = "jack";
        System.out.println("在cry中使用age = " + age);


    }

    public void eat(){
        System.out.println("在eat中使用age = " + age);
    }

}
  1. 在java编程中,主要的变量就是属性(成员变量)和局部变量

  2. 我们说的局部变量一般是指在成员方法中定义的变量,【举例 Cat类:cry】

  3. java中作用域的分类

    1. 全局变量:也就是属性,作用域为整个类体 Cat类:cry eat等方法使用属性【举例】
    2. 局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中
  4. 全局变量可以不赋值,直接使用因为有默认值,局部变量必须赋值后,才能使用,因为没有默认值【举例】

使用细节

VarScopeDetail.java

public class VarScopeDetail {
    public static void main(String[] args) {

        Person1 person1 = new Person1();
        person1.say();

    }
}

class Person1{
    String name = "jack";
    public void say(){
        //细节 属性和局部变量可以重名,访问时遵循就近原则
        String name = "king";

        System.out.println("say() name = " + name);
    }

    public void hi(){
        String address = "北京";
//        String address = "上海";//错误,重复定义变量
        String name = "jjj";
    }

}
  1. 属性和局部变量可以重名,访问时遵循就近原则

  2. 在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名

  3. 属性生命周期较长,伴随着对象的创建而创建,伴随着对象的死亡而死亡。局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而死亡。即在一次方法调用过程中

  4. 作用域不同

    1. 全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
    2. 局部变量:只能在本类中调用
  5. 修饰符不同

    1. 全局变量/属性可以加修饰符
    2. 局部变量不可以加修饰符

构造方法/构造器

看一个需求:前面在创建人类对象时,是先把一个对象创建好后,再给它的年龄和姓名属性赋值如果现在要求创建人类对象时,就直接指定这个对象的年龄和姓名,该怎么做?这时就可以使用构造器

基本语法

[修饰符] 方法名(形参列表){
    方法体;
}

说明:

  1. 构造器的修饰符可以默认
  2. 构造器没有返回值
  3. 方法名和类名必须一样
  4. 参数列表 和 成员方法一样的规则
  5. 构造器的调用系统完成

基本介绍

构造方法又叫构造器,是类的一种特殊方法,它的主要作用是完成对新对象的初始化,它有以下几个特点

  1. 方法名和类名相同
  2. 没有返回值
  3. 在创建对象时,系统会自动调用该类的构造器完成对对象的初始化

快速入门

完成问题:在创建人类的对象时,就直接指定这个对象的年龄和姓名Constructor.java

使用细节

ConstructorDetail.java

package 构造器;

public class Constructor {
    public static void main(String[] args) {
//        Person p1 = new Person("smith",80);
//        System.out.println(p1.name + p1.age);
        Dog dog01 = new Dog();
        System.out.println(dog01.age);
        Dog dog02 = new Dog("xiaobai",18);
        System.out.println(dog02.age);
        System.out.println(dog02.name);

    }
}

class Person{
    String name;
    int age;
    public Person(String pName,int pAge){
        name = pName;
        age = pAge;


    }
}


class Dog{

    int age;
    String name;
    public Dog(){
        age = 18;
    }
    public Dog(String pName,int pAge){
        name = pName;
        age = pAge;
    }


}
  1. 一个类可以定义多个不同的构造器,即构造重载,比如:我们可以再给Person类定义一个构造器,用来创建对象的时候,只指定人名,不需要指定年龄
  2. 构造器名和类名要相同
  3. 构造器没有返回值
  4. 构造器是完成对象的初始化,并不是创建对象
  5. 在创建对象时,系统自动的调用该类的构造方法
  6. 如果程序员没有定义构造方法,系统会自动给类生成一个默认无参构造方法(也叫默认构造方法),比如Person(){}使用javap指令反编译看看
  7. 一旦定义了自己的构造器,默认构造器就覆盖了,就不能在使用默认的无参构造器,除非显式的定义一下,即:Person(){}}

流程分析

  1. 加载Person类信息(person.class),只会加载一次

  2. 在堆中分配空间(地址)

  3. 完成对象初始化

    1. 默认初始化 age = 0,name = null
    2. 显式初始化age = 90,name = null
    3. 构造器的初始化 age = 20,name = xiaobai
  4. 在对象在堆中的地址返回给p(p是对象名,也可以说是对象的引用)

this

问题引出

先看代码,分析问题

This01.java

package this关键字;

public class This01 {
    public static void main(String[] args) {

        Dog dog01  = new Dog("xiaobai",5);
        System.out.println(dog01.hashCode());
        dog01.info();

    }
}
class Dog{
    String name;
    int age;
    public Dog(String name,int age){
        this.name = name;
        this.age = age;
    }
    public void info(){

        System.out.println(name + " \t" + age + "\t");
        System.out.println(this.hashCode());

    }

}

什么是this

java虚拟机会给每个对象分配this,代表当前对象。

使用细节

ThisDetail.java

package this关键字;

public class ThisDetail {
    public static void main(String[] args) {
        T t1 = new T();

    }
}

class T{

    public T(){
        //如果要在一个构造器访问另一个构造器必须在第一句
        this("woshinibaba",1);
        System.out.println("默认构造器");

    }

    public T(String name,int age){
        System.out.println("String name,int age构造器被调用");
    }



    public void f1(){
        System.out.println("f1方法");
    }
    public  void f2(){
        System.out.println("f2方法");
        //调用本类方法f1
        //第一种方法
        f1();
        //第二种方法
        this.f1();
    }

}
  1. this关键字可以用来访问本地类的属性,方法,构造器
  2. this用于区分当前类的属性和局部变量(正常访问是就近原则,如果有局部变量就可以使用this访问类属性)
  3. 访问成员方法的语法:this.方法名(参数列表)
  4. 访问构造器语法:this(参数列表); 注意:只能在构造器中使用
  5. this不能在类定义的外部使用,只能在类定义的方法中使用