【Java复健指南05】构造器与作用域

构造器

public class Constructor01{
	public static void main(String[] agrs){
		//当我们new一个对象时,直接通过构造器指定名字和年龄
		Person p1 = new Person("smith", 80);
		System.out.println("p1的信息如下");
		System.out.println("p1对象name=" + p1.name); //smith
		System.out.println("p1对象age=" +p1.age);//80
		//添加构造器之后,类在实例化时必须初始化其属性
		//实际上不写构造器java也会默认创建一个空构造器
	}
}

//在创建人类的对象时,就直接指定这个对象的年龄和姓名1/
class Person {
	String name;
	int age;
	//构造器
	//1.构造器没有返回值,也不能写void
	//2.构造器的名称和类Person—样
	//3. (String pName, int pAge)是构造器形参列表,规则和成员方法一样
	public Person(String pName, int pAge){
		System.out.println("构造器被调用~~完成对象的属性初始化");
		name = pName;
		age = pAge;
	}
}

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

public class ConstructorDetail{
	public static void main(String[] agrs){
		Person p1 = new Person("king", 40);//第1个构造器
		Person p2 = new Person("tom");//第2个构造器

	}
}

class Dog{
/*
	默认构造器Dog(){
		
			}
*/	
}

class Person {
	String name;
	int age;//默认0
	//第1个构造器
	public Person(String pName, int pAge) {
		name = pName;
		age = pAge;
	}
	//第2个构造器,只指定人名,不需要指定年龄
	public Person(String pName){
		name = pName;
	}
}

例子

public class ConstructorExercise{
	public static void main(String[] agrs){
		/*
		在前面定义的Person类中添加两个构造器:
			第一个无参构造器:利用构造器设置所有人的age属性初始值都为18
			第二个带pName和pAge两个参数的构造器:使得每次创建Person对象的同时初始化对象的age属性值和name属性值。
			分别使用不同的构造器,创建对象.
		*/
		Person p1 = new Person();
		Person p2 = new Person("ag", 24);

	}
}

class Person{
	int age;
	String name;
	public Person(){
		System.out.println("构造器1被调用~~完成age的属性初始化");
		age = 18;

	}

	public Person(String pName, int pAge){
		System.out.println("构造器2被调用~~完成对象的属性初始化");
		name = pName;
		age = pAge;
	}
}

练习1

public class Homework09{
	public static void main(String[] agrs){
		/*
		9.定义Music类,里面有音乐名name、音乐时长times属性,
		并有播放play功能和返回本身属性信息的功能方法getlnfo. 
		*/
	}
}

class Music{
	String name;
	int times;
	public Music(String name, int times) {
		this.name = name;
		this.times = times;
	}
	//播放play功能
	public void play(){
		System.out.println("音乐" + name +"正在播放中...时长为"+ times +"秒")}
	//返回本身属性信息的功能方法getInfo
	public String getInfo(){
		return "音乐"+name +"播放时间为" +times;
	}
}

练习2

public class Homework12{
	public static void main(String[] agrs){
		/*
		12.创建一个Employee类,属性有(名字,性别,年龄,职位,薪水),
		提供3个构造方法,可以初始化
		(1)(名字,性别,年龄,职位,薪水),
		(2)(名字,性别,年龄)
		(3)(职位,薪水).要求充分复用构造器
		*/
	}
}

class Employee{
	String name;
	String sex;
	int age;
	String zhiwei;
	int sal;

	public Employee(String name, String sex, int age, String zhiwei, int sal){
		this.name = name;
		this.sex = sex;
		this.age = age;
		this.zhiwei = zhiwei;
		this.sal = sal;
	}

	public Employee(String name, String sex, int age){
		this.name = name;
		this.sex = sex;
		this.age = age;

	}

	public Employee(String zhiwei, int sal){
		this(name,gender, age);//使用到前面的构造器

		this.zhiwei = zhiwei;
		this.sal = sal;
	}

}

作用域

基本使用

面向对象中,变量作用域是非常重要知识点

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

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

3.java中作用域的分类
全局变量:也就是属性,作用域为整个类体Cat类: cry eat等方法使用属性
局部变量:也就是除了属性之外的其他变量,作用域为定义它的代码块中!

4.全局变量(属性)可以不赋值,直接使用,因为有默认值,局部变量必须赋值后,才能用,因为没有默认值。

public class Scope01{
	public static void main(String[] agrs){
        
	}
}

class cat {
	//全局变量:也就是属性,作用域为整个类体Cat类 :cry eat等方法使用属性
	//属性在定义时,可以直接赋值
	int age = 10;//指定的值是10

	// {
	// 	int num = 100;//仅能在该代码块中使用
	// }
	double weight;//不赋值 默认值是0.0

	public void cry(){
		//1.局部变量一般是指在成员方法中定义的变量
		//2. n和name就是局部变量
		//3. n和name的作用域在cry方法中
		int n = 10;
		String name = "jack";
		System.out.println("在cry中使用属性age=" +age);
	}

	public void eat() {
		system.out.println("在eat中使用属性age="+age);
		// System.out.println("在eat中使用cry的变量 name=" + name);//错误

	}
}

注意事项

1.属性和局部变量可以重名,访问时遵循就近原则
2.在同一个作用域中,比如在同一个成员方法中,两个局部变量,不能重名。
3.属性生命周期较长,伴随着对象的创建而创建,伴随着对象的销毁而死亡。
局部变量,生命周期较短,伴随着它的代码块的执行而创建,伴随着代码块的结束而销毁。即在一次方法调用过程中。
4.作用域范围不同
全局变量/属性:可以被本类使用,或其他类使用(通过对象调用)
局部变量:只能在本类中对应的方法中使用
5.修饰符不同
全局变量/属性可以加修饰符局部变量不可以加修饰符

public class ScopeDetail{
	public static void main(String[] agrs){

	}
}

class T {
//全局变量
//属性:可以被本类使用,或其他类使用(通过对象调用)
	public void test(){
		Person p1 = new Person();
		System.out.println(p1.name); //jack
	}

	public void test2(Person p){
		system.out.print1n(p.name); //jack
	}
}

class Person{
	//属性可以加修饰符,局部变量不能
	public int age = 18;
	String name = "jack";

	public void say(){
		//属性和局部变量可以重名,访问时遵循就近原则
		String name = "king";
		System.out.println("say() name = "+ name);
	}
	public void hi(){
		String address = "北京";
		String name = "hyn";
	}
}

This

This理解:
new新对象p1之后会在中开辟新空间(设为k1),k1中会保存对象里面的值(比如name,age等),同时会生成一个隐藏变量this,该变量指向空间本身.此时this.name指的就是k1中的name,对应p1的对象属性
简单地说,“哪个对象调用,this就代表哪个对象”

public class This01{
	public static void main(String[] agrs){
		Dog dog1 = new Dog("大社", 3);
		System.out.println("dog1的hashcode=" + dog1.hashCode());
		//dog1调用了info()方法
		dog1.info();
		System.out.println("============");
		Dog dog2 = new Dog("大黄", 2);
		System.out.println("dog2的hashcode=" + dog2.hashCode());
		dog2.info();
	}
}

class Dog{//类
	String name;
	int age;
	// public Dog(String dName, int dAge){
	// 	name = dName;
	// 	age = dAge;
	// }

	//如果我们构造器的形参,能够直接写成属性名,就更好了
	//但根据变量作用域原则,构造器的name就是局部变量了而不是属性
	//相当于传入的参数只是在构造器这的name,和类的属性没关系,
	//因此打印的时候还是打的默认值

	public Dog(String name, int age){//构造器
		// name = name;
		// age = age;
		//this.name就是当前对象的属性name
		this.name = name;
		//this.age就是当前对象的属性age
		this.age = age;
		System.out.println("this(Dog).hashCode=" + this.hashCode());
	}

	public void info(){	System.out.println("this(info).hashCode=" + this.hashCode());
		System.out.println(name + "\t" + age + "\t");
	}
}

this的注意事项和使用细节

	1. this关键字可以用来访问本类的属性、方法、构造器
	2. this用于区分**当前类的属性**和**局部变量**
	3. 访问成员方法的语法:this.方法名(参数列表)
	4. 访问构造器语法:this(参数列表);注意只能在构造器中使用
	5. **this不能在类定义的外部使用**,只能在类定义的方法中使用。
public class ThisDetail{
	public static void main(String[] agrs){
		// T t1 = new T()
		// t1.f2();
		T t2 = new T();
	}
}

class T{
	/*
	细节:访问构造器语法:this(参数列表);
	注意只能在构造器中使用(即只能在构造器中访问另外一个构造器)
	ps:访问构造器语法:this(参数列表);必须放在第一条语句
	*/
	public T() {
		System.out. println("T()构造器");//这里去访问 T(String name,int age)
		this("jack", 100);
	}
	public T(String rgme, int age){
		System.out.println("T(String name,int age)构造器");
	}

	//this关键字可以用来访问本类的属性
	public void f3(){
		String name = "smith";
		//传统方式,就近原则name为sm,因为局部变量没有num就回属性去拿
		System.out.println("name=" +name + " num=" + num); // smith 100
		//也可以使用this访问属性,回属性去拿
		System.out.println("name=" + this.name + " num=" + this.num);//jack 100

	}
	//访问成员方法的语法:this.方法名(参数列表准)
	public void f1(){
		System.out.println("f1() 方法..");
	}

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

例子

public class ThisExercise{
	public static void main(String[] agrs){
		Person p1 = new Person("ts", 20);
		Person p2 = new Person("ag", 24);

		//p1输入的参数为this,p2的为比较值
		System.out.println("p1和p2比较的结果="+ p1.compareTo(p2));
	}
}

class Person{
	int age;
	String name;

	//构造器
	public Person(String name, int age){
		this.name = name;
		this.age = age;
	}

	public boolean compareTo(Person p){
		// if(p.name == this.name && p.age == this.age){
		// 	return true;
		// }else{
		// 	return false;
		// }

		//简化写法
		return this.name.equals(p.name) && this.age == p.age;
	}
}
posted @ 2022-10-16 15:46  dayceng  阅读(33)  评论(0编辑  收藏  举报