20220719_第七小组_张红睿_学习笔记
Java基础第七天
1.掌握
IDEA输出快捷键:sout->System.out.println();
2.重点
2.1 类的三种关系
- has-a:包含关系,是整体与部分的关系,生命周期相同。如:人有一双眼睛。作为属性。
- is-a:继承关系,父类与子类,具有很高的耦合度。使用extends关键字。作为子类。
- use-a:使用关系,其中一个使用另一个,但是不负责销毁,也就是生命周期不同。作为参数。
2.2 this关键字
- this指向当前的实例化对象,属于对象,不属于类。成员方法中的this,谁调用该方法,this就指向谁。
- this不能用在static方法中。
- this通常用在赋值,尤其是构造器赋值。
- 若在构造方法中出现了this关键字,则代表当前正在构造的对象。
- 若在成员方法中出现了this关键字,则代表当前正在调用的对象。
- this关键字本质上就是当前类类型的引用变量。
this工作原理:在构造方法中和成员方法中访问成员变量时,编译器会加上this.的前缀,当不同对象调用同一个方法时,由于调用方法的对象不同导致this关键字不同,从而this.方式访问的结果也就随之不同。
使用方式:
当局部变量名与成员变量名相同时,在方法体中会优先使用局部变量(就近原则),若希望使用成员变量,则需要在成员变量的前面加上this.的前缀,明确要求该变量是成员变量。
this关键字除了可以通过this.的方式调用成员变量和成员方法外,还可以作为方法的返回值。
在构造方法的第一行可以使用this()的方式来调用本类中的其他构造方法。
示例:
public class Student{
String name;
int age;
public Student(){} // 无参构造
public Student(String name, int age){ // 有参构造
this.name = name; // 当创建实例化对象时,对象的name属性就等于传入的形参name。
this.age = age;
}
}
2.3 封装
2.3.1 定义
封装(Encapsulation)是面向对象方法的重要原则,就是把对象的属性和操作(或服务)结合为一个独立的整体,并尽可能隐藏对象的内部实现细节。
封装是把过程和数据包围起来,对数据的访问只能通过已定义的接口。面向对象计算始于这个基本概念,即现实世界可以被描绘成一系列完全自治、封装的对象,这些对象通过一个受保护的接口访问其他对象。封装是一种信息隐藏技术,在Java中通过关键字private、protected和public实现封装。
封装把对象的所有部分组合在一起,封装定义程序如何引用对象的数据,封装实际上使用方法将类的数据隐藏起来,控制用户对类的修改和访问数据的程度。适当的封装可以让程序代码更容易理解和维护,也加强了程序代码的安全性。
2.3.2 作用
- 对象的数据封装特性彻底消除了传统结构方法中数据与操作分离所带来的种种问题,提高了程序的可复用性和可维护性,降低了程序员保持数据与操作内容的负担。
- 对象的数据封装特性还可以把对象的私有数据与公共数据分离开,保护了私有数据,减少了可能的模块间的干扰,达到降低程序复杂性、提高可控性的目的。
2.3.3 示例
封装第一步:将变量私有化,加private关键字。
public class Student{
// 将变量私有化
private String name;
private int age;
public Student(){} // 无参构造
public Student(String name, int age){ // 有参构造
this.name = name;
this.age = age;
}
}
封装第二步:提供公有化的get和set方法,对变量进行合理值判断。
public class Student{
// ①将变量私有化
private String name;
private int age;
// ②提供get/set方法,进行合理值判断。
public void setName(String name){
this.name = name;
}
public String getName(String name){
return this.name;
}
public void setAge(int age){
this.age = age >= 0 ? age : 0;
}
publiv int age(){
return this.age;
}
public Student(){} // 无参构造
public Student(String name, int age){ // 有参构造
this.name = name;
this.age = age;
}
}
封装第三步:在公有的构造方法中调用set方法。
public class Student{
...
public Student(){} // 无参构造
public Student(String name, int age){ // 有参构造
// ③公有的构造方法调用set方法赋值
// this.name = name;
// this.age = age;
this.setName(name);
this.setAge(age);
}
}
3.注意
- 保证每个类都有无参构造器
- 代码封装经验:看业务需求
- 属性私有化
- 空指针异常和下标溢出异常是运行时出现的异常。
- null是个关键字
- this可调用构造函数,但必须在构造函数中使用
4.案例
点击查看代码
//Demo.java
import java.util.Scanner;
/**
* 程序功能:
* 1.主界面提供登录和注册功能
* 2.进入注册界面后可以通过输入用户名和密码进行注册
* 3.进入登录界面后可以进行查询个人信息, 并且可以进行修改个人信息和删除个人账户(删除后可再注册)
* 4.在登录界面后用户无法修改、删除、查看非自己外的用户信息, 本例通过不询问键盘输入用户名的方式完成, 即用户名只在登录时保存, 登陆后的操作不改变其值。
*/
public class Demo {
private static User[] users; // 用户数组
private static int length; // 用户数组有效长度
private static int maxLength; //
// Java中不支持缺省参数, 但可通过函数重载来实现!!!!!!!
/**
* 判断是否添加成功
* @param username 用户名
* @param password 密码
* @return 添加成功返回true, 否则返回false
*/
public static boolean addUsers(String username, String password){
// 数组为空 初始化
if(users == null){
users = new User[5];
length = 0;
maxLength = 5;
} else if (length == maxLength) { // 数组为满 扩容
maxLength += 5;
User[] tmpUser = new User[maxLength];
for (int i = 0; i < length; i++) {
tmpUser[i] = users[i];
}
users = tmpUser;
}
// 不允许用户名重复
if(isExistUser(username)){
return false;
}
// 添加用户
users[length] = new User(username, password);
length++;
return true;
}
/**
* 判断用户名是否存在
* @param username 用户名
* @return 存在返回true, 不存在返回false
*/
public static boolean isExistUser(String username){
if(selectUser(username) != -1)
return true;
return false;
}
public static boolean removeUser(String username){
int index = selectUser(username);
if(index == -1){
System.out.println("用户不存在!");
return false;
}
// 删除操作
users[index] = null;
int i = index;
// 移位
for (; i < length - 1; i++) {
users[i] = users[i + 1];
}
users[i] = null;
length--;
return true;
}
/**
* 通过指定用户名得到对应下标
* @param username 待输入用户名
* @return 返回对应下标, 不存在则返回-1
*/
private static int selectUser(String username){
for (int i = 0; i < length; i++) {
if(users[i].getUsername().equals(username))
return i;
}
return -1;
}
public static void updateUser(String username, String password, String newUsername, String newPassword){
int index = selectUser(username);
// 首先判断用户是否存在
if(index == -1){
System.out.println("用户不存在!");
return;
}
// 当用户名与新用户名不一致即需要改用户名时, 要判断新的用户名是否已存在
if(!username.equals(newUsername) && selectUser(newUsername) == -1){
// 满足条件 即可修改
users[index].setUsername(newUsername);
users[index].setPassword(newPassword);
return;
} else if (!username.equals(newUsername) && selectUser(newUsername) != -1) {
System.out.println("新用户名存在, 请换一个用户名!");
return;
}
// 当用户名与新用户名一致时, 即不需要修改用户名, 直接改密码即可
users[index].setPassword(newPassword);
}
/**
* 判断标志flag合法性
* @param flag 待判断标志
* @param str 检测的字符数组
* @return 合法返回true、否则返回false
*/
private static boolean isFlagValid(String flag, String ...str){
for (String s : str) {
if(s.equals(flag))
return true;
}
return false;
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String flag, username = null, password = null;
System.out.println("欢迎进入用户登录系统!");
// 整体循环
while(true){
// 该循环判断输入标识合法性
while (true){
System.out.println("*****************");
System.out.println("请选择序号: 1.登录 2.注册 0.退出");
flag = sc.next();
if(isFlagValid(flag, "1", "2", "0"))
break; // 合法则跳出死循环
System.out.println("输入不合法,请重新输入!");
}
switch (flag){
case "1":
System.out.println("请输入您的用户名:");
username = sc.next();
if(!isExistUser(username)){
System.out.println("无此用户名!");
break;
}
System.out.println("请输入您的密码:");
password = sc.next();
if(!users[selectUser(username)].getPassword().equals(password)){
System.out.println("密码输入错误!");
break;
}
boolean isReturn = true;
while(isReturn) {
while (true) {
System.out.println("*****************");
System.out.println("请选择功能: 1.修改 2.删除 3.显示 9.返回 0.退出");
flag = sc.next();
if (isFlagValid(flag, "1", "2", "3", "9", "0"))
break; // 合法则跳出死循环
System.out.println("输入不合法,请重新输入!");
}
switch (flag) {
case "1":
System.out.println("请输入新用户名: (可与原用户名相同)");
String newUsername = sc.next();
System.out.println("请输入新密码: (可与原密码相同)");
String newPassword = sc.next();
updateUser(username, password, newUsername, newPassword);
username = newUsername;
break;
case "2":
while (true) {
System.out.println("确认删除?(y/n)");
flag = sc.next();
if (isFlagValid(flag, "y", "n", "Y", "N"))
break;
System.out.println("输入不合法,请重新输入!");
}
if (flag.equals("y") || flag.equals("Y")) {
removeUser(username);
System.out.println("删除成功!");
isReturn = false;
break;
}
System.out.println(username + "未删除!");
break;
case "3":
users[selectUser(username)].show();
break;
case "9":
System.out.println("系统即将返回到登录界面, 请稍等!");
isReturn = false;
break;
case "0":
System.out.println("系统即将退出, 欢迎再次使用!");
return;
}
}
break;
case "2":
while(true) {
System.out.println("请输入用户名: ");
username = sc.next();
if(!isExistUser(username)){
break;
}
System.out.println("用户名已存在");
}
System.out.println("请输入密码: ");
password = sc.next();
if(addUsers(username, password))
System.out.println("恭喜您注册成功!");
break;
case "0":
System.out.println("系统即将退出, 欢迎再次使用!");
return;
}
}
}
}
// User.java
public class User {
private String username;
private String password;
public String getUsername(){
return this.username;
}
public String getPassword(){
return this.password;
}
public void setUsername(String username){
this.username = username;
}
public void setPassword(String password){
this.password = password;
}
public User(){}
public User(String username, String password){
this.setUsername(username);
this.setPassword(password);
}
public void show(){
System.out.println("用户名: " + this.getUsername() + "\t密码: " + this.getPassword());
}
}
开始:
注册:
登录:
显示:
修改:
删除: