什么时候用构造器(构造方法)赋值:
1. 看创建对象是为了什么?
- 如果创建对象只是为了调用这个类的方法,建议使用无参构造器
- 如果创建对象需要使用到对象的某个属性,可以使用有参构造器赋值
大家养成一个习惯!
如果一个类我们手写了构造器,原来的无参构造器失效
我们养成的一个习惯:保证每个类都有无参构造器
public Person() {
}
注意:构造器在创建对象时被调用
构造器(构造方法)也可以被重载!!!
this关键字:
- this代表的是当前类的对象,this代表的是当前方法的调用者
- 当使用对象调用属性时,调用的是成员变量
- this既然是代表方法的调用者,它实际上和对象的作用是一样的。
- 既可以调属性,也可以调方法
*this调用构造器的要求*
1. 必须在构造器中使用this调用构造器
2. 必须是第一句话
面向对象之封装:
在现实生活中有很多封装的案例,例如:手机、电脑等等都是属于封装。
对于手机的封装:
首先是对手机部件的封装,给他们一个坚硬的外壳,保证内部部件的安全;
还有的就是对他们功能的封装,对于手机的某个功能例如计算器,我们并不需要直到这个计算器的计算功能是如何实现的,只需要知道怎么去使用这个计算功能即可。
封装有什么作用
- 保证内部结构安全
- 屏蔽复杂,暴露简单(对功能的封装)
在代码中封装的作用
在一个类体中的数据,假设对代码进行封装后,对于代码的调用者来说是方便的,调用者不需要考虑这个代码的具体实现,只需要有一个简单的操作入口便能使用这个代码的功能(例如:java.util.Arrays这个工具类中有一个sort方法,可以对数组进行排序,这里我们并不需要考虑排序功能是如何实现的,只需要会使用这个sort方法便能使用数组排序的功能);对于类体中安全级别较高的数据,可以使用封装使外部人员不能访问,保证数据安全。
对属性进行封装
将类中的属性私有化(每个属性都使用private修饰)
对外提供简单的操作入口(为每一个属性都定义一对Setter/Getter方法)
public class Test {
public static void main(String[] args){
Student stu1 = new Student();
stu1.setNo(1);
stu1.setName("张三");
stu1.setGender('男');
stu1.setAge(12);
System.out.println("学号:" + stu1.getNo() + ",姓名:" + stu1.getName() + ",性别:" + stu1.getGender() + ",年龄:" + stu1.getAge());
}
}
class Student {
private int no; //学号
private String name; //姓名
private char gender; //性别
private int age; //年龄
//学号的Setter/Getter方法
public void setNo(int no) {
this.no = no;
}
public int getNo() {
return this.no;
}
//姓名的Setter/Getter方法
public void setName(String name) {
this.name = name;
}
public String getName() {
return this.name;
}
//性别的Setter/Getter方法
public void setGender(char gender) {
this.gender = gender;
}
public char getGender () {
return this.gender;
}
//年龄的Setter/Getter方法
public void setAge(int age) {
this.age = age;
}
public int getAge() {
return this.age;
}
}
注:
对于年龄属性的设置可以通过Setter方法设置一个关卡,用于过滤所有年龄不合法的数据。
//年龄的Setter/Getter方法
public void setAge(int age) {
if(age <= 0 || age >=120) {
System.out.println(“您的年龄不合法,请重新赋值”);
}else {
this.age = age;
}
}
对员工管理系统进行封装
import java.util.Scanner;
import java.util.Arrays;
public class ManageSystem {
static int[] nos = new int[2]; //用于存放员工号
static String[] names = new String[2]; //用于存放员工姓名
static int empNo = 1000; //员工编号
static int empSum = 0; //员工人数
static boolean isContinue = false; //是否继续
//删除index索引位置的nos和names的元素
public static void delete(int index) {
for(int j=index; j<nos.length; j++){
if(j == nos.length-1) {
nos[j] = 0;
names[j] = null;
break;
}
//位移
nos[j] = nos[j+1];
names[j] = names[j+1];
}
}
对nos和names扩容,扩容原来的2倍
public static void arrayExpansion() {
int[] new_nos = new int[nos.length * 2];
String[] new_names = new String[names.length * 2];
for(int i=0; i<nos.length; i++) {
new_nos[i] = nos[i];
new_names[i] = names[i];
}
nos = new_nos;
names = new_names;
}
//找到nos或names中指定元素的位置,找不到返回-1
public static int indexOf(Object obj) {
if(obj instanceof Integer) {
Integer no = (Integer)obj;
for(int i=0; i<nos.length; i++) {
if(no == nos[i]) return i;
}
}
if(obj instanceof String) {
String name = (String)obj;
for(int i=0;i<names.length; i++){
if(name.equals(names[i])) return i;
}
}
return -1;
}
public static void main(String[] args){
System.out.println("欢迎使用员工管理系统!");
Scanner sc = new Scanner(System.in);
while(true) {
System.out.println("请选择功能:1.添加员工 2.查询员工 3.修改员工 4.删除员工");
int flag = sc.nextInt();
switch (flag) {
case 1:
//添加
isContinue = true;
while(isContinue) {
System.out.print("请输入员工姓名:");
String name = sc.next();
//超出扩容
if(empSum >= nos.length) {
arrayExpansion();
}
//赋值并更新
nos[empSum] = ++empNo;
names[empSum++] = name;
System.out.println("你已添加成功!");
System.out.println("是否继续添加?(true/false):");
isContinue = sc.nextBoolean();
}
break;
case 2:{
//要求根据工号查询
boolean isFindAll = false;
System.out.print("查询所有员工true;查询单个员工false:");
isFindAll = sc.nextBoolean();
if(isFindAll) {
//查询所有员工
if(names[0] == null) {System.out.println("没有任何员工"); break;}
for(int i=0; i<nos.length; i++) {
System.out.println("员工编号:" + nos[i] + "\t员工姓名:" + names[i]);
}
} else {
System.out.print("请输入你想查询的员工工号:");
int in_empNo = sc.nextInt();
//找到返回下标,找不到返回-1
int index = indexOf(in_empNo);
System.out.println(index != -1 ? ("员工编号:" + nos[index] + "\t员工姓名:" + names[index]) : "未找到该员工\n");
}
break;
}
case 3:{
//修改
System.out.print("请输入你想修改的员工工号:");
int in_empNo = sc.nextInt();
int index = indexOf(in_empNo);
if(index == -1) {
//没找到
System.out.print("员工号有误\n");
} else {
//显示原有信息
System.out.println("员工编号:" + nos[index] + "\t员工姓名:" + names[index]);
System.out.print("请输入新名字:");
String new_name = sc.next();
//更新新名字
names[index] = new_name;
System.out.println("修改成功!修改结果如下");
System.out.println("员工编号:" + nos[index] + "\t员工姓名:" + names[index]);
}
break;
}
case 4: {
//删除
System.out.print("请输入你想删除的员工工号:");
int in_empNo = sc.nextInt();
int index = indexOf(in_empNo);
if(index == -1) {
//没找到
System.out.print("你要删除的员工并不存在!\n");
} else {
//显示原有信息
System.out.println("员工编号:" + nos[index] + "\t员工姓名:" + names[index]);
System.out.print("是否确认删除该员工?(true/false):");
boolean isDel = sc.nextBoolean();
if(isDel) {
//删除
delete(index);
//更新员工数量
empSum--;
System.out.println("删除成功!");
} else {
System.out.println("已取消删除操作!");
}
}
}
break;
default:
System.out.println("无效数值,请重新选择");
break;
}
}
}
}
空指针异常:NullPointException
什么情况下会出现空指针异常?
由于引用数据类型的默认值(初始值是null,空引用)运行期异常:
3个异常:
1. 数组下标越界
2. 内存溢出(错误)
3. 空指针
知识点:了解