Java基础(七)——面向对象基础(二)构造方法、全局变量与局部变量、static关键字、构造代码块

Java基础(七)——面向对象基础(二)

一、构造方法

1、无参构造方法

调用属性是 对象.属性来调用,调用方法是 对象.方法()来调用。可以看到区分属性跟方法就在于后面有没有小括号,有就是方法。

实例化对象的时候,是这样:

	Teacher tea1 = new Teacher()		// 实例化一个对象

可以看到,等号右边,这个类有个小括号,这个有在调用一个方法,就是构造方法。

a、构造方法的调用

每次实例化一个对象的时候,就会调用构造方法:

public class Teacher{
    
    
	int id;
	String name;

	public Teacher(){
    
    		// 无参构造方法
	System.out.println("这里是无参构造方法");
	}
}

可以看到,上面的构造方法,名字跟类是一样的。

所以,使用构造方法,就是:public 类名

b、无参构造方法

这个构造方法,没有接收参数,所以称为无参构造方法。

构造方法如果有 return 语句,会报错,所以构造方法不能有返回值。

构造方法无论我们在不在类里面定义,都能实例化对象。说明构造方法默认存在。

2、有参构造方法

当无参构造方法接收参数进行数据处理,就是有参构造方法。

public Teacher(int i,String str){
    
    	//有参构造方法
	 System.out.println("这里是有参构造方法");
}

a、有参构造方法创建对象

因为每次实例化对象都会执行构造方法,所以可以通过有参构造方法,在实例化对象的时候就赋值,就可以无需通过 set 方法来赋值。

public Teacher(int i,String str){
    
    	// 有参构造方法
	id = i;
	name = str;
	System.out.println("这里是有参构造方法");
}

b、通过有参构造方法实例化对象

在实例化的对象的时候就进行赋值:

Teacher tea1 = new Teacher(1,"张三);		// 实例化对象的同时进行赋值

这样创建出来的 tea1 对象就有了id和姓名,就不需要set 方法来进行初始赋值

3、构造方法总结

  1. 构造方法不能有返回值,方法名和类名一致。
  2. 无参构造方法默认存在。
  3. 无参构造方法作用:初始化属性和创建对象。
  4. 有参构造方法作用:创建对象的同时给一个或者多个属性赋值。-------相当于无参+多个set()
  5. 当有参构造方法创建的时候,默认的无参构造方法会消失。需要使用的时候必须手动创建。

二、全局变量与局部变量

1、全局变量与局部变量

因为贯彻见词知意,所以构造方法形参这块,不应该用像 i ,str 这类单词,应该:

public class Teacher{
    
    
	int id;
	String name;
	
	public Teacher(int id,String name ){
    
    	// 有参构造方法
		id = id;
		name = name ;
		System.out.println("这里是有参构造方法");
	}
}

如果按照以上代码运行,实例化对象,对象的 id 只能是0,name 肯定是 null。这里就要说到局部变量与全局变量的概念了。

如果在类里面,方法外面定义的变量,则是全局变量,如果是方法里面,则是局部变量。

那么全局变量与局部变量,都重名时,使用哪个变量呢?
答案是使用作用域范围小的那个变量。

所以这里使用的是方法内部的局部变量,因为只初始化了,没有赋值,所以使用的是初始化的值。

2、this

所以这里可以通过 this 这个关键字,指定这个变量是当前对象的变量,就不会产生这种作用域范围错误的问题:

public class Teacher{
    
    
	int id;
	String name;

	public Teacher(int id,String name){
    
    	// 有参构造方法
		this.id = id;
		this.name = name ;
		System.out.println("这里是有参构造方法");
	}
}

这里通过this指定的id,就是类内部,那个全局变量的id。

3、局部变量不能做的事

  1. 局部变量不能存在访问修饰符,比如:public,private.
  2. 局部变量不存在初始值,比如:只初始化不赋值int id

4、this调用方法

this.方法()意思是调用当前对象的方法:

public class Teacher{
    
    
	int id;
	String name;

	public Teacher(int id,String name){
    
    	// 有参构造方法
		this.id = id;
		this.name = name ;
		this.method1();		// 调用下面的方法1
		System.out.println("这里是有参构造方法");
	}

	public void method1(){
    
    
		System.out.println("这里是方法1");
	}
}

上面的代码中,this.method1()会调用到下面的 method1(),

5、this调用无参构造方法

既然this代表当前对象,因此,this(),代表的是当前类对象的无参构造方法,必须注意的是:通过this调用构造方法必须在构造方法中的第一句。

6、总结

  1. 全局变量:定义在类中,作用域在整个类,拥有初始值和访问修饰符。
  2. 局部变量:定义在方法中,作用域只在方法中,没有初始值和不能存在访问修饰符。
  3. 当局部变量和全局变量同名的时候, 使用的时候会优先使用作用域更小的变量。
  4. this:代表当前对象
  5. this.属性——调用当前类对象的属性
  6. this.方法() – 调用当前类对象的方法
  7. this() – 调用当前类对象的无参构造方法,且通过 this 调用构造方法必须在构造方法中的第一句。

三、static关键字

1、static修饰变量(静态属性)

实例属性是每个对象各自持有的独立空间(多份),对象单方面修改,不会影响其他对象。
比如:对象1的年龄与对象2的年龄,对象1年龄改变,对象2的年龄不会改变。

被 static 修饰的属性,称为静态属性。static int age;

但是,静态属性是整个类共同持有的共享空间(一份),任何对象修改,都会影响其他对象。
在这里插入图片描述
在这里插入图片描述
运行后的结果是:
在这里插入图片描述

可以看到,本来第一个老师的money应该是1000,但这里却变成了2000。因为money是静态属性,共用一块内存空间,后面的tea2赋值了money是2000,所以后面的对象输出money都是2000。

2、static修饰方法(静态方法)

static修饰的方法称为静态方法。

a、类直接调用静态方法

静态方法可以被类直接调用,不需要经过实例化对象。

定义类:

public class Animal {
    
    
    String name;
    int leg;
    static String sex;

    public static void method1(){
    
    		// 静态方法
        sex = "母";
        System.out.println("123"+","+sex);
    }
}

类直接调用:

Animal.method1();		// 类能直接调用

b、静态方法只能调用静态属性

public class Teacher {
    
    
    static int id;    //静态属性
    int num;

    public static void method01(){
    
    			//静态方法
        System.out.println("静态方法");
        //静态方法不允许调用非静态属性
        //System.out.println(num);
        System.out.println(id);
        
        //静态方法不允许调用普通方法
        //method02();
    }
    //普通方法
    public void method02(){
    
    
    }
}

静态方法只能调用静态属性,通过测试先后顺序就可以得知,加了 static 关键字的属性或者方法,也就是静态属性/方法,比普通方法和属性更早创建,在创建静态属性/方法后,普通属性/方法还没有初始化,所以自然也无法调用普通属性/方法。

3、static(静态)无法修饰构造方法

static 修饰的属性/方法,可以被类直接调用,有点共享的思想,也先于其他属性/方法执行。

static 无法修饰构造方法,因为:构造方法是对象初始化时候执行的方法,不初始化,则不执行后面的方法,所以构造方法是源头。因为是初始化才能使用,所以不存在共享的概念,初始化之后,后面才有机会调用,所以也不需要提前执行。所以也就没有添加 static 的必要。所以 static 无法修饰的属性/方法。

4、构造代码块

public class Teacher {
    
    

    {
    
    		// 构造代码块从这里开始
        System.out.println("这里是代码块");		// 这里是构造代码块
    }		// 构造代码块从这里结束


    public Teacher(){
    
    
        System.out.println("这里是无参构造方法");
    }
}

通过测试可知,构造代码块执行顺序优于构造方法。

同理,静态构造代码块,执行顺序优于构造代码块。

5、static 修饰的静态构造代码块

静态构造代码块有且仅有一次执行
测试:

public class Test4 {
    
    
    public static void main(String[] args) {
    
    
    
        // 测试2:静态构造代码块有且仅有一次执行

        Teacher tea1 = new Teacher();
        Teacher tea2 = new Teacher();
    }
}
public class Teacher {
    
    
    public Teacher(){
    
    
        System.out.println("这里是无参构造方法");
    }
    {
    
    
        System.out.println("这里是构造代码块");
    }
    static {
    
    
        System.out.println("这里是静态构造代码块1");
    }
}

结果是:
在这里插入图片描述

可以看到,静态构造代码块只执行了一次,所以,静态构造代码块有且仅有一次执行。

6、静态构造代码块与静态属性

静态构造代码块与静态属性的实行顺序是:按代码从上到下执行,谁先在前面谁先执行。

7、总结

static:静态的,被static修饰的代码会随着字节码文件(也就是.class文件)优先于类加载进内存。

static 修饰的属性为静态属性,内存中所有对象共享一份数据,通过类名直接调用。

static 修饰的方法为静态方法,直接通过类名调用,一般工具类中存在静态方法,静态方法只能调用静态属性。

static 修饰的构造代码块为静态构造代码块。在类被使用的时候,有且仅有一次执行,优先于构造代码块和构造方法。

静态属性/静态构造代码块 > 构造代码块 > 构造方法

直接通过类调用时,只会触发静态构造代码块和静态属性。 其他的均如:构造代码块和构造方法都不会触发。
只有实例化对象时,才会触发构造代码块和构造方法。

猜你喜欢

转载自blog.csdn.net/qq_41824825/article/details/121125080