JavaSE(4)

构造器


也叫构造方法 ---constructor,本质上是一个方法,但是有特殊性

特点

  1. 方法名和类名一致, 唯一允许首字母大写的方法名

  2. 没有返回值声明, 甚至连void也不允许

  3. 不能被关键字 : static, final, synchronize, native, abstract等修饰

  4. 不能像普通方法一样随意调用, 只能调用一次. 某个对象的生命周期中只能调用一次.

总结

  1. **Java****语言中,每个类都至少有一个构造器
  2. 默认构造器的修饰符与所属类的修饰符一致**
  3. 一旦显式定义了构造器,则系统不再提供默认构造器
  4. 类可以创建多个重载的构造器
  5. 父类的构造器不可被子类继承
  6. 构造器重载, 还可以连环调用, 但是一定要保证有一个构造器中是没有this(…). 防止无限递归.

this()

  • 特殊调用必须是构造器中的第一行. 对其他构造器的调用必须要先于此构造器的特有代码, 最终要体现在继承中子类对象的初始化要晚一些.

  • 在java中,this关键字比较难理解,它的作用和其词义很接近。

  • 它在方法内部使用,即这个方法所属对象的引用;谁调用this就是谁.

  • 它在构造器内部使用,表示该构造器正在初始化的对象。

    注意

    1. **使用this()必须放在构造器的首行!

    2. 使用this调用本类中其他的构造器,保证至少有一个构造器是不用this的。

    3. 	class TeacherV0 { 
      	
      		// 成员变量(member), 成员可以使用修饰符修饰, 注意 : 局部变量无法使用访问控制修饰符 
      		// private表示私有的意思, 一旦私有, 外部无法访问, 只能在类内部访问
      		// 这样的处理称为 "封装", 成员私有化.
      		private String name = "某老师"; // 属性如果没有显式赋值, 它的值就是默认值0
      		private int age; // 缺省值是0
      		private String gender = "未知";
      		
      		// 构造器重载, 还可以连环调用, 但是一定要保证有一个构造器中是没有this(). 防止无限递归.
      		// this(...) 特殊调用必须是构造器中的第一行. 对其他构造器的调用必须要先于此构造器的特有代码
      		public TeacherV0() { // 无参, 调用简单, 功能单一, 有其特殊性, 创建对象简单, 无参构造器将来要为子类专供.
      			/*
      			this.name = "佟刚";
      			this.age = 40;
      			this.gender = "男";
      			*/
      			this("佟刚", 40); // 对其他构造器的调用
      			System.out.println("Teacher()..."); // 此构造器的特有代码
      		}
      		
      		public TeacherV0(String name, int age) {
      			/*
      			this.name = name;
      			this.age = age;
      			this.gender = "男";
      			*/
      			this(name, age, "男"); // 重载的构造器的调用, 必须使用this();
      			System.out.println("Teacher(String, int)...");
      		} 
      		
      		public TeacherV0(String name, int age, String gender) { // 全参, 功能强大, 调用复杂
      			//this();
      			this.name = name;
      			//this.age = age;
      			setAge(age); // 统一的参数合法性判断.
      			this.gender = gender;
      			System.out.println("Teacher(Stintg, int, String)...");
      		}
      		
      		/* 这种方法也是允许存在的, 但是不要这样写, 容易引起误会.*/
      		public void TeacherV0(String name) {
      			System.out.println("我是普通方法, 不是构造方法, 我是捣乱的, 忽略我");
      		}
      		
      		// set方法有参无返回
      		public void setName(String name) { // 间接设置属性的方法,称为set方法
      			//name = name; // 变量访问的就近原则, 会导致左面的name不是属性, 而是局部变量.
      			this.name = name; 
      			// this表示当前对象. 当局部变量参数和成员变量冲突时, 成员变量必须加上限定
      		}
      		
      		// get方法无参有返回
      		public String getName() { // 间接获取name属性值的方法, 称为get方法
      			return this.name;
      		} 
      		
      		// 使用方法间接给属性赋值的好处是 可以加上 逻辑判断, 使得数据得到保护...
      		public void setAge(int age) {
      			if (age < 0 || age > 150) { // 如果数据非法, 直接弹栈
      				System.out.println("参数年龄太大");
      				return; // 提前弹栈, 会导致this.age没有刷新值. 保持了原有的0
      			}
      			this.age = age;
      		}
      		
      		public int getAge() {
      			return this.age;
      		}
      		
      		public void setGender(String gender) {
      			this.gender = gender;
      		}
      		
      		public String getGender() {
      			return this.gender;
      		}
      		
      		// 成员方法(member)
      		public void lesson() {
      			System.out.println(this.say() + "老师在上课"); // 成员互访
      		}
      		
      		public void eat(String some) {
      			System.out.println(name + "老师在吃" + some);
      		}
      		
      		// 返回对象的详细信息字符串, 所有属性值的拼接
      		public String say() {
      			return "姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender;
      		}
      }
      
      

每日一考_day08

  1. 什么是封装? 如何封装?

成员私有化, 防止外部直接访问. 成员包括属性, 方法, 构造器, 内部类.

使用private修饰成员, 就可以封装.

  1. 什么是构造器,作用是什么? 有什么特点(4点)

    也称为构造方法, 在对象的创建过程中会由JVM调用它, 作用是对对象进行初始化工作

    • 方法名必须和类名一致, 唯一允许使用首字母大写的方法.
    • 不声明返回值类型, 甚至连void也没有.
    • 不能被关键字:abstract, static ,final, synchronized, native等 修饰
    • 不能像普通方法一样随意调用, 只能在对象创建时调用仅有的一次.
  2. 创建一个对象的步骤(7步)

    1. 在方法区要检查要创建的对象所属的类模板信息是否存在(类是否已经加载)
    2. 如果不存在, 必须由类加载器加载类模板, 加载到方法区中, 永久保存它.
    3. 如果存在, 则不加载, 保证类模板在方法区中只有一份.
    4. 依据类模板中的所有属性定义信息, 在GC区中开辟空间. 获取到对象的地址.
    5. 把此空间全部写0. 底层操作 : memset(内存地址, 0, 长度); 效果是所有属性拥有0
    6. 检查属性是否有显式赋值, 如果有, 则执行显式赋值.
    7. 执行构造方法, 进一步对属性进行赋值等初始化工作.
    8. 把对象地址返回给创建者
  3. this关键字表示什么含义?

    this表示的是对象, 当前对象

    1. 如果是在构造器中, this表示正在创建中的对象, this.成员.
    2. 如果是在构造器中, this(…) 表示对其他重载的构造器的调用.

    要求 :

    1. this(…) 必须在构造器的首行,

    2. 一定要保证至少有一个构造器中没有this(…);

      1. 如果是在方法中或属性的使用中, 表示的是正在访问这个属性或方法的对象的引用
      Xxx ref1 = new Xxx();
      ref1.method(); // 对象方法的调用必须要有对象.
      Xxx ref2 = new Xxx();
      ref2.method();
      ref1.field = “值”;
       
      class Xxx {
      
      ​      String field = this.xxx();
      ​      public void method() {
      ​          // ref1.method() 调用中, this 代表就是ref1
      ​          // ref2.method() 调用中, this 代表就是ref2
      	}
      
      }
      

      this 就是指调用者对象

      对象 包括属性, 或者说是拥有属性

      对象地址 : 对象在GC区中的第一个字节的编号. 也称为首地址

对象关联

对象关联 : 一个对象完全拥有另外一个类的对象.

关联目的 : 随时随时地方便地使用另一个对象.

如何关联 : 在前者的类中把另外一个类的对象作为属性即可. 属性是成员, 成员意味着它们之间可以直接互访

一旦把对象作为我的属性, 需要处理全参构造器, 因为是属性也要提供get/set方法, 改造say()方法

public class Teacher {
	
	private String name;
	private int age;
	private String gender;
	private Computer myComputer; // 对象关联
	
	public Teacher() {}
	
	public Teacher(String name, int age, String gender, Computer myComputer) {
		this.name = name;
		this.age = age;
		this.gender = gender;
		this.myComputer = myComputer;
	}
	
	public void setMyComputer(Computer myComputer) {
		this.myComputer = myComputer;
	}
	
	public Computer getMyComputer() {
		return myComputer;
	}
	
	public void setName(String name) {
		this.name = name;
	}
	
	public String getName() {
		return name;
	}
	
	public void setAge(int age) {
		this.age = age;
	}
	
	public int getAge() {
		return age;
	}
	
	public void setGender(String gender) {
		this.gender = gender;
	}
	
	public String getGender() {
		return gender;
	}
	
	public String say() {
		return "姓名 : " + name + ", 年龄 : " + age + ", 性别 : " + gender + ", 我的电脑 : " + myComputer.say();
	}
	
	//public void lesson(Computer computer) {
	public void lesson() {
		System.out.println(name + "老师在使用电脑[" + myComputer.say() + "]上课");
	}
	
	public void film() {
		System.out.println("使用电脑[" + myComputer.say() + "]看电影");
	}
	
}

package

  • 包 : 用于管理功能类似的多个类.

​ package 包名.子包名.子子包名.子子子包名; // 这个语句总是在源文件中第一行

  • 作用 : 告诉编译器, 当前源文件中的类, 编译后的.class文件放入指定的包目录中.

​ 通常情况下包有4层

​ package 机构类型.机构名称.项目名称.模块名称; // 包名全部小写

​ package com.atguigu.javase.javabean;

  • 一旦使用了package, 会带来两个麻烦

    ​ 1. 编译时必须加上选项-d : javac -d 目标目录路径 源文件名

​ -d表示目标目录

​ 常见写法 : javac 空格 -d 空格 . 空格 源文件名

​ 2. 使用时, 如果是跨包使用本类, 在别的包的类中必须使用全限定名称来使用本类,

​ 全限定名称就是 所有包名.类名 : 包名.子包名.子子包名.子子子名包.类名;

​ 比如在测试类中, 要想使用本类. com.atguigu.javase.javabean.Teacher

​ 练习 : 把Person类和Phone类都打包在com.atguigu.javase.javabean包中

​ 把PersonTest类打包在com.atguigu.javase.test包中

​ 在测试类中, 使用全限定类名来使用Person类和Phone类, 编译所有程序, 运行测试.

数组

  • 数组 : 一组相同任意类型的数据的组合, 便于统一管理.

  • 数组 : 由多个元素组成, 每个元素相当于是数组对象的属性

  • 数组属于引用类型, 数组的数据则是对象.

  • 数组声明 :

​ 元素数据类型[] 数组名;

  • 数组创建 :

​ 数组名 = new 元素数据类型[元素个数];

public class ArrayTest {
	
	public static void main(String[] args) {
		// 声明 : 元素数据类型[] 数组名;
		int[] arr; // 此时没有数组对象存在的.
		// 创建 : new 元素数据类型[元素个数];
		arr = new int[5]; // 在GC区中创建一个元素有5个的int型数组. 数组对象创建好以后, 所有元素都有缺省值0
		// 数组元素的定位(访问), 通过首地址(数组名)[偏移量(也称为下标, 索引, 脚标)]
		// 每个元素都是一个小变量.
		arr[2] = 4;
		arr[0] = 3;
		arr[arr[0]] = 1;
		arr[arr[2]] = 5;
		// 分析每个元素的值
		System.out.println(arr[0]); // 3
		System.out.println(arr[1]); // 0
		System.out.println(arr[2]); // 4
		System.out.println(arr[3]); // 1
		System.out.println(arr[4]); // 5
	}
}

每日一考_day09


  1. 类模版信息保存在内存中的什么位置,里面包含了哪些信息,类模版信息的特点和作用是什么?

    在堆内存的永久区(方法区)

    类模版中包含的信息有:

    • 属性的定义信息(修饰符,数据类型,属性名,显示值)
    • 所有方法的代码。(不是在运行中的状态),如果要运行,必须把它压入栈中执行。
    • 构造器,类名、父类、接口、注解。。。
  2. 数组是什么? 什么类型的数据可以创建数组?

    一组相同任意类型的数据的组合,便于统一管理

    任意数据类型,包括基本型和引用型

  3. 如何声明并创建数组?有几种方式?

    声明: 数据类型[] 数组名;

    创建: new 元素数据类型[长度];

    声明和创建 : 元素数据类型[] 数组名 = new 元素数据类型[长度];

    静态方式1 :适用于数据量小,元素值确定的情况

    ​ 元素数据类型[] 数据名 = new 元素数据类型[]{值1,值2......};

    静态方式2 : 使用受限:声明和初始化必须在同一条语句上才可以这样

    ​ 元素数据类型[] 数组名 = {元素值1 ,值2 .....};

  4. 判断

    • 数组的长度可以随意变化 F
    • 数组的元素类型和数组类型是一回事 F
    • 数组的访问是通过数组名.下标实现的 F
    • 数组的访问方式是数组名(首地址)+ 偏移量算出来的 T
    • 数组的元素类型可以随意变化 F
Student[] stuArr = new Student[3]; // 1

stuArr[0] = new Student(20,"小明","男");

stuArr[1] = new Student(30,"小丽","女");

for (int i = 0;i < stuArr.length;i++){
	System.out.println(stuArr[i].say());
}

在1位置处有几个对象被创建,什么对象? 1,String[]

以上的代码有没有问题?如何改进? 有问题

  • 将stuArr[2]赋上值(Student对象)
  • 加判断语句,若为null不say()即可
posted @ 2020-03-30 13:02  Earnest杰  阅读(125)  评论(0编辑  收藏  举报