类作为数据类型,应用场景
文章目录
作为声明
User[] users = new User[3];
User user1 = new User();
作为参数的数据类型
void addUser(User user){
System.out.println(user.uid);
System.out.println(user.name);
}
*/
void fight(Plant plant) {
// 在当前类中,可以用this表示自己的对象
System.out.println(this.name+"开始攻击"+plant.name);
while (plant.hp>0) {
plant.hp -= this.attack-plant.defense;
System.out.println(plant.name+"还剩"+plant.hp+"血");
// 通过Thread.sleep方法让程序停顿
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
System.out.println("战斗结束,"+plant.name+"被"+this.name+"干掉了");
}
调用方法时,就必须传递该类型的对象(实例)
public static void main(String[] args) {
// 创建僵尸对象
Zombie zombie1 = new Zombie("普通僵尸",10,8,100);
Zombie zombie2 = new Zombie("路障僵尸",10,16,100);
// 通过僵尸对象调用fight方法
// 先声明一个植物对象
Plant plant1 = new Plant("豌豆射手", 20, 5, 100);
Plant plant2 = new Plant("坚果",0, 9, 200);
//zombie1.fight(plant1);
//zombie1.fight(plant2);
zombie2.fight(plant1);
}
作为成员变量(属性)的类型
public class UserManager {
// 成员字段
User[] users ;
//User[] users = new User[10];
// 构造方法中给数组赋值
UserManager(){
users = new User[10];
}
}
public class UserManagerDemo {
public static void main(String[] args) {
UserManager userManager = new UserManager();
System.out.println(userManager.users[0]); // null
}
}
把僵尸角色和植物角色定义在一个Game的类中
public class Game {
//用对象类型作为字段的数据类型
// 僵尸角色
Zombie zombie;
// 植物角色
Plant plant;
void fight() {
zombie.fight(plant);
}
}
执行操作, 给字段赋值要按照对象类型的要求来赋值
public static void main(String[] args) {
// 创建Game的实例
Game game = new Game();
game.plant = new Plant("豌豆射手", 20, 5, 100);
game.zombie = new Zombie("路障僵尸",10,16,100);
game.fight();
}
作为返回值类型
在UserManager类中设计一个寻找用户信息的方法
/**
* 定义一个方法: 通过id找到用户
* @param id 要找的用户的编号
* @return 返回扎到的用户对象,如果没有则返回null
*/
User findById(int id) {
// 实现寻找目标用户的业务
// 1. 遍历数组
for (User user : users) {
//2. 用参数id和数组中每一个对象的id比较
// 还必须判断迭代变量是否是null值
if(user!=null && id == user.id) {
//3. 相等则表示找到了目标
return user;
}
}
// 如果循环结束都没有找到,就返回null
return null;
}
利用面向对象的思想来设计用户管理的程序
思路图
1.User类
public class User {
// 用户编号
int id ;
// 用户姓名
String name;
// 用户手机
String phone;
// 用户密码
String pwd;
//用户年龄
int age;
}
2.UserManager类
public class UserManager {
// 成员字段
User[] users;
// User[] users = new User[10];
// 构造方法中给数组赋值
UserManager(){
users = new User[10];
}
/**
* 定义一个方法: 通过id找到用户
* @param id 要找的用户的编号
* @return 返回扎到的用户对象,如果没有则返回null
*/
User findById(int id) {
// 实现寻找目标用户的业务
// 1. 遍历数组
for (User user : users) {
//2. 用参数id和数组中每一个对象的id比较
// 还必须判断迭代变量是否是null值
if(user!=null ) {
if( id == user.id) {
//3. 相等则表示找到了目标
return user;
}
}
/*
* if(user!=null && id == user.id) { //3. 相等则表示找到了目标 return user; }
*/
}
// 如果循环结束都没有找到,就返回null
return null;
}
/**
* 向数组中添加用户对象的方法
* @param user 目标对象
*/
void add(User user){
// for循环中判断某个位置是否为null
// 满足条件, 就把目标user赋值
// 然后跳出循环
// users[0] = user;
}
}
3.UserManagerDemo类
public class UserManagerDemo {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
UserManager userManager = new UserManager();
// 在数组中添加一些User对象
/*但是如果把数组声明为private私有, 将不能直接访问了
*
* System.out.println(userManager.users[0]); // null
* userManager.users[0] = new User(); userManager.users[0].id = 1001;
* userManager.users[0].name = "张三丰";
*
* userManager.users[1] = new User(); userManager.users[1].id = 1002;
* userManager.users[1].name = "张无忌";
*/
/*
* System.out.println("添加操作:"); System.out.println("用户编号"); int id =
* scanner.nextInt(); System.out.println("用户姓名"); String name = scanner.next();
*/
//调用add方法
//User user = new User(id,name,);
//userManager.add(user);
// 调用findById方法
System.out.println("请输入一个用户的id");
int id= scanner.nextInt();
User findUser = userManager.findById(id);
//根据返回值提示用户
if(findUser == null) {
System.out.println("查无此用户");
return;
}
System.out.println("你要找的用户信息是:"+findUser.name);
}
}
使用foreach循环遍历对象类型的数组的过程分析
public static void main(String[] args) {
// 对象类型的数组的遍历操作
User[] users = new User[2];
users[0] = new User("a","133",20);
users[1] = new User("b","134",21);
// 用for遍历数组
/*
* for(int i=0;i<users.length;i++) {
* System.out.println("姓名:"+users[i].name+",手机号:"+users[i].phone); }
*/
//System.out.println("-----------------");
// foreach循环 , 也叫做 for..in循环
// in表示注入: 把数组中的每一个元素都分别依次注入到一个临时变量中
// 该变量也成为迭代变量
for(User u :users) {
System.out.println("姓名:"+u.name+",手机号:"+u.phone);
}
}
包和访问权限
1.包
Java要求所有的代码都必须声明包(文件夹),如果没有主动声明,java会将代码放在默认包default package中
作用: 代码可以重复,包是绝对不会重复的
声明规范: 使用url域名的反转形式 com.gxa.userManager.Demo
公司域名: alibaba.com
产品名称: druid(数据库连接池产品)
最终的命名就是: com.alibaba.druid.Driver
(小知识)公司中的开发人员占比
开发部的人员配比:
前端: 2-3人
后端(java) : 4-6 保持为前端开发人员的2-3倍
测试: 1人
运维: 1人
2.声明:
使用关键字package , 利用域名的反转形式, 且必须放在代码的最顶行(注释除外)
语法: package 包的声明;
在jdk中, 通常是java包
com: 放oracle后来添加的内容和sun子包
java包: jdk1.0开始到现在的最核心的内容
jdk中系统自带的一些包:
util 常用的工具类 Scanner/Random
lang(language语言,默认包),自动被加载的包,如果要使用这个包中的类,不需要手动引入, System /String , 因为这些类使用特别频繁
io: 流的操作(输入输出,文件)
sql: 数据库操作需要用的包
net: 网络通信要使用
3.引入(在当前代码中使用其他包中的类):
使用关键字import
语法: import 完整包的路径+类(全限定名); / import 完整包路径+*;
区别: *可以表示此包中的任意类, 当代码中使用多个该包中的类的时候, 用一个*就可以实现它们全部的引入了
// 2. 引入操作必须在类的声明之前定义
import java.util.Scanner;
// 使用*表示任意
import java.util.*;
注意:
- *不是全部加载,用到什么类就去找到并加载目标
- 如果要表示类的时候,除了使用import,还可以用全限定名称方式(包+类)
Scanner: 类名 java.util: 报名
java.util.Scanner : 限定名(反射中就要使用)
// 全限定名:
java.util.Scanner scanner = new java.util.Scanner(System.in);
String inputString = scanner.next();
System.out.println(“inputString:”+inputString);
//还有一个比较有用的应用场景: 如何在一个代码中同时实例化两个不同包User的实例
User user8 = new User();
user8.id = 1;
com.gxa.day9.User user9 = new com.gxa.day9.User();
user9.name = "zhang";
- 如果是同一个包, 类可以互相访问, 不需要import(导入也可以,但没有必要)*
package com.gxa.day9;
// UserManager和User在同一个类中, 所以User使用的时候不需要引入
public class UserManager {
// 成员字段
User[] users;
// User[] users = new User[10];
// 构造方法中给数组赋值
UserManager(){
users = new User[10];
}
//... 省略后续代码
}
-
com.gxa. * ; com表示父包, gxa是子包, *只能代表类,只能在import的最末尾
-
声明顺序: package > import > class
-
JDK中javaSE所有的代码基本都集中在java和javax包(extend)中
-
如果引用了其它公司的声明包(或自定义包)通常都以com(org)开头
-
Java的包的命名规范: 域名的反转
-
在开发中,我们会用包作为功能区分:
entity : 实体类(User/Person/Student/Player)
dao: 数据持久化(存储数据的操作)
service: 业务逻辑的包
controller: 控制器包
经过改造后的程序结构如下图:
访问权限(modifier)
1.概念:
是否允许被访问(许可)
Java为了保证代码的安全调度,设置了不同的权限,使得不具备权限的时候禁止代码被访问(安全性的目的)
2.目的:
代码的安全性(访问和修改)
3.实现方法
通过访问权限修饰符(modifier)实现
Java中共有4种访问权限
访问权限类型 | 作用 | 当前类中 | 同一个包 | 不同包 | 作用 | 项目中 |
---|---|---|---|---|---|---|
public(公共) | 可以修饰类和成员(字段/方法) | y | y | y | Java工程中访问该权限没有任何限制 | 常用(类和类中的成员方法) |
protected | 只能修饰成员(字段和方法) | y | y | 且非继承:n 继承: y | 将访问权限主要针对继承中来访问 | 在继承中应用 |
default(默认,什么权限都不加) | 可以修饰类和成员 | y | y | n | 将访问权限限制在包的内部 | 不常用 |
private(私有) | 只能修饰成员 | y | n | n | 将访问权限限制在类的内部 | 声明模型类中的成员属性, 设计模式中也应用(单例模式) |
在eclipse中声明类时,可选的访问权限
利用访问权限实现对User类的改造:
/**
* 用户类型
* @author bilei
* @date 2021年7月28日
*/
public class User {
// 用户编号
private int id ;
// 通过一组方法对外提供访问和修改的操作
// getXXX 和 setXXX (getter/setter)
// 当字段有了对应的getter和setter之后, 就可以称它为属性
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
// 用户姓名
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
// 用户手机
private String phone;
// 用户密码
private String pwd;
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
//用户年龄
private int age;
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
/*
* if(age>0) { this.age = age; }else { this.age = 0; }
*/
}
public User(int id, String name, String phone, String pwd, int age) {
this.id = id;
this.name = name;
this.phone = phone;
this.pwd = pwd;
this.age = age;
}
public User() {
}
}
static
1.概念:
是一个修饰符 , 用来修饰成员字段和成员方法(也可以修饰类)
当静态方法中调用了类中的成员属性,就要求成员属性也必须声明为静态
// static静态字段
static int count = 1000;
//静态方法
public static void f2() {}
2.作用:
被静态修饰的内容从属于类本身,不属于任何对象
产生的原因: 类中存在一类方法,它们和该类的对象并没有直接关系
在内存中的位置:
3.操作:
在类的外部访问时:
类名.静态成员
在类的内部访问时:
有一类方法,随着调用它的对象的不同而产生不同的结果 – 实例方法
有一类方法,不会根据调用对象的不同产生变化,只需要类直接调用 – 静态方法
public class UserDao {
// 实例字段
int i = 1;
// static静态字段
static int count = 1000;
//实例方法
public void f1() {
// 访问静态方法 可以
f2();
// 访问实例字段 可以
System.out.println(i);
// 访问静态字段 可以
System.out.println(count);
}
//静态方法
public static void f2() {
// 静态方法不能访问实例方法 不可以
//f1();
// 访问其它静态方法 可以
f3();
// 访问实例字段 不可以
// System.out.println(i);
// 访问静态子弹 可以
System.out.println(count);
}
public static void f3() {
}
}
调用方 | 实例成员(字段和方法) | 静态成员 |
---|---|---|
实例方法 | Y | Y |
静态方法 | N | Y |
用一个简单的记忆方法: 只有静态方法才会被要求只能调用其它静态成员(包括方法和字段), 其它没有任何要求
因为final不可改变的特点,static常常和final连用
public static final double PI = 3.14;
4.静态代码段
在类中,由static修饰的一个{}语句块
作用:随着类的内存的分配而分配,只要类发生操作就会立即执行: 程序运行时就从文件中读取内容
static {
users = new User[3];
}
静态在使用的注意事项:
- 静态的使用并非必须的, 当类中的操作的执行变化和对象无关,只可能和参数有关, 这一类方法适合使用static声明
- 开发中通常适合应用在工具类中(参考StringUtil)
- 实体类不能用静态声明, 因为实体类需要产生不同的对象(实例)
5.开发中的应用场景
-
开发中,常用于操作类UserDao/工具类XXXUtils中的方法声明
-
静态代码段
例如,在使用数据库操作中,把和数据库的连接操作放在静态代码块中,保证一旦类工作就会先建立和数据库的连接,
StringUtil的设计:
public class StringUtil {
// 判断一个字符串是否为空(null或""): isEmpty , 实现数据简单的校验
/**
* 判断一个字符串是否为空(null或"")的方法
* @param target 被判断的目标字符串
* @return 判断结果, 如果为null或""就返回true,反之返回false
*/
public static boolean isEmpty(String target) {
// 字符串比较, 通常把不确定的内容放在equals方法中作为参数,确定的内容作为调用者
if(target == null || "".equals(target)) {
return true;
}
return false;
}
}
用static优化UserDemo交互中方法的设计
public class UserDemo {
// 为了用户输入,而准备的Scanner
private static Scanner scanner = new Scanner(System.in);
// 创建UserManager类实例的过程
private static UserDao userDao = new UserDao();
//根据功能的不同, 拆分为不同的方法
// 访问权限 [static] 返回类型 方法名(参数列表){ 方法体 }
// 是否需要参数的判断依据: 是否需要传入数据
// 是否需要返回值的判断依据: 是否需要传出数据
// static的判断依据: 是不是一种实例方法的特性(根据对象不同而产生不同的调用结果)
public static void addView() {
// 通过交互获取用户的特征
/*
* System.out.println("请输入用户的id"); int id = scanner.nextInt();
*/
System.out.println("请输入用户的姓名");
String name = scanner.next();
System.out.println("请输入用户的手机号");
String phone = scanner.next();
System.out.println("请输入用户的密码");
String pwd = scanner.next();
System.out.println("请输入用户的年龄");
int age = scanner.nextInt();
// 声明一个新的User对象
// 被添加的用户对象必须是局部
User user = new User();
user.setName(name);
user.setPhone(phone);
user.setPwd(pwd);
user.setAge(age);
// 调用核心方法add
boolean success = userDao.add(user);
if (success) {
System.out.println("添加操作成功");
} else {
System.out.println("添加失败,系统人数已到上限");
}
}
public static void findByIdView() {
// 交互
System.out.println("请输入要查询的用户id");
int id = scanner.nextInt();
//调用findById方法
User findUser = userDao.findById(id);
// 如果结果不为null,才能输出用户信息
if(findUser != null) {
System.out.println("用户的编号:"+findUser.getId()+"\t用户的姓名:"+findUser.getName()+"\t用户的手机号:"+findUser.getPhone());
}else {
System.out.println("查无此人");
}
}
public static void findAllView() {
userDao.findAll();
}
public static void updateView() {
//修改操作执行前,先根据id判断被修改的用户是否存在
//当用户存在, 修改某一个特征, 其他特征被查询得到,没有改变
System.out.println("请输入要修改的用户id");
int id = scanner.nextInt();
User findUser = userDao.findById(id);
if(findUser != null) {
fieldFlag:while(true) {
// 交互, 获取用户需要修改的目标
System.out.println("请选择要修改的特征: 1.姓名 2.手机号 3.密码 4.年龄 5.是否可见 6.退出");
int choiceField = scanner.nextInt();
switch (choiceField) {
case 1:
System.out.println("请输入要修改的姓名");
String newName = scanner.next();
findUser.setName(newName);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
System.out.println("修改为: 1.可见 2.不可见");
//boolean visible = scanner.nextBoolean();
int visible = scanner.nextInt();
if(visible == 1) {
findUser.setVisible(true);
}else if(visible == 2) {
findUser.setVisible(false);
}else {
System.out.println("没有该选项");
}
break;
case 6:
break fieldFlag;
default:
System.out.println("没有该选项");
break;
}
}
// 交互完成后, 调用核心方法
// 作用: 把修改后的对象传入update方法, update方法要调用数据库操作完成最终修改
userDao.update(findUser);
System.out.println("修改成功");
}else {
System.out.println("查无此人");
}
}
public static void deleteView() {
// 交互
System.out.println("请输入要删除的用户id");
int id = scanner.nextInt();
// 先判断该id的用户是否存在
User user = userDao.findById(id);
// 如果该user对象是非空,表示存在,存在才删除
if(user != null) {
userDao.delete(id);
System.out.println("删除成功");
}else {
System.out.println("没有该用户,删除失败");
}
}
//main方法也是一个static方法
// main的执行和对象无关
public static void main(String[] args) {
// 欢迎信息
System.out.println("你好,欢迎使用XXX银行CRM系统");
// 采用死循环, 给用户提示: 1.添加 2.根据id查询 3.全查询 4.修改 5.删除 6.退出
flag: while (true) {
System.out.println("请选择操作: 1.添加 2.根据id查询 3.全查询 4.修改 5.删除 6.退出");
int choice = scanner.nextInt();
switch (choice) {
case 1:
// 改成调用addView方法
addView();
break;
case 2:
findByIdView();
break;
case 3:
findAllView();
break;
case 4:
updateView();
break;
case 5:
deleteView();
break;
case 6:
// 退出
// break flag;
// return;
// 结束系统运行的方法
System.exit(0);
default:
System.out.println("没有该选项");
break;
}
}
}
}
将视图操作单独提取出来定义在类中:
思路:
- 每个操作都是独立的类(add/ findById/findAll/delete/update)
- 都适合用static封装方法: show
- 在使用到UserDao的时候, 通过参数传递引用
AddView类:
public class AddView {
// 为了用户输入,而准备的Scanner
private static Scanner scanner = new Scanner(System.in);
/**
* 显示添加操作的方法
*/
public static void show(UserDao userDao) {
// 通过交互获取用户的特征
/*
* System.out.println("请输入用户的id"); int id = scanner.nextInt();
*/
System.out.println("请输入用户的姓名");
String name = scanner.next();
System.out.println("请输入用户的手机号");
String phone = scanner.next();
System.out.println("请输入用户的密码");
String pwd = scanner.next();
System.out.println("请输入用户的年龄");
int age = scanner.nextInt();
// 声明一个新的User对象
// 被添加的用户对象必须是局部
User user = new User();
user.setName(name);
user.setPhone(phone);
user.setPwd(pwd);
user.setAge(age);
// 调用核心方法add
boolean success = userDao.add(user);
if (success) {
System.out.println("添加操作成功");
} else {
System.out.println("添加失败,系统人数已到上限");
}
}
}
DeleteView类:
public class DeleteView {
// 为了用户输入,而准备的Scanner
private static Scanner scanner = new Scanner(System.in);
public static void show(UserDao userDao) {
// 交互
System.out.println("请输入要删除的用户id");
int id = scanner.nextInt();
// 先判断该id的用户是否存在
User user = userDao.findById(id);
// 如果该user对象是非空,表示存在,存在才删除
if (user != null) {
userDao.delete(id);
System.out.println("删除成功");
} else {
System.out.println("没有该用户,删除失败");
}
}
}
FindAllView类:
public class FindAllView {
public static void show(UserDao userDao) {
userDao.findAll();
}
}
FindByIdView类:
public class FindByIdView {
// 为了用户输入,而准备的Scanner
private static Scanner scanner = new Scanner(System.in);
/**
* 根据id查找用户操作的交互方法
*/
public static void show(UserDao userDao) {
// 交互
System.out.println("请输入要查询的用户id");
int id = scanner.nextInt();
//调用findById方法
User findUser = userDao.findById(id);
// 如果结果不为null,才能输出用户信息
if(findUser != null) {
System.out.println("用户的编号:"+findUser.getId()+"\t用户的姓名:"+findUser.getName()+"\t用户的手机号:"+findUser.getPhone());
}else {
System.out.println("查无此人");
}
}
}
UpdateView类:
public class UpdateView {
// 为了用户输入,而准备的Scanner
private static Scanner scanner = new Scanner(System.in);
public static void show(UserDao userDao) {
// 修改操作执行前,先根据id判断被修改的用户是否存在 //当用户存在, 修改某一个特征, 其他特征被查询得到,没有改变
System.out.println("请输入要修改的用户id");
int id = scanner.nextInt();
User findUser = userDao.findById(id);
if (findUser != null) {
fieldFlag: while (true) {
// 交互, 获取用户需要修改的目标
System.out.println("请选择要修改的特征: 1.姓名 2.手机号 3.密码 4.年龄 5.是否可见 6.退出");
int choiceField = scanner.nextInt();
switch (choiceField) {
case 1:
System.out.println("请输入要修改的姓名");
String newName = scanner.next();
findUser.setName(newName);
break;
case 2:
break;
case 3:
break;
case 4:
break;
case 5:
System.out.println("修改为: 1.可见 2.不可见");
// boolean visible = scanner.nextBoolean();
int visible = scanner.nextInt();
if (visible == 1) {
findUser.setVisible(true);
} else if (visible == 2) {
findUser.setVisible(false);
} else {
System.out.println("没有该选项");
}
break;
case 6:
break fieldFlag;
default:
System.out.println("没有该选项");
break;
}
}
// 交互完成后, 调用核心方法 // 作用: 把修改后的对象传入update方法, update方法要调用数据库操作完成最终修改
userDao.update(findUser);
System.out.println("修改成功");
} else {
System.out.println("查无此人");
}
}
}
Main类(主入口所在的类)
public class Main {
// 为了用户输入,而准备的Scanner
private static Scanner scanner = new Scanner(System.in);
// 创建UserManager类实例的过程
private static UserDao userDao = new UserDao();
//main方法也是一个static方法
// main的执行和对象无关
public static void main(String[] args) {
// 欢迎信息
System.out.println("你好,欢迎使用XXX银行CRM系统");
// 采用死循环, 给用户提示: 1.添加 2.根据id查询 3.全查询 4.修改 5.删除 6.退出
flag: while (true) {
System.out.println("请选择操作: 1.添加 2.根据id查询 3.全查询 4.修改 5.删除 6.退出");
int choice = scanner.nextInt();
switch (choice) {
case 1:
// 改成调用addView方法
//addView();
AddView.show(userDao);
break;
case 2:
FindByIdView.show(userDao);
break;
case 3:
//findAllView();
FindAllView.show(userDao);
break;
case 4:
//updateView();
UpdateView.show(userDao);
break;
case 5:
//deleteView();
DeleteView.show(userDao);
break;
case 6:
// 退出
// break flag;
// return;
// 结束系统运行的方法
System.exit(0);
default:
System.out.println("没有该选项");
break;
}
}
}
}
面向对象操作的两点思路
-
当要执行非操作,就需要找到该方法的所在类,并实例化,通过实例化的对象调用
-
当要执行静态操作,直接用类名访问(.)
面向对象的核心: 三大特征
封装
继承
多态
开发中的应用场景
-
开发中,常用于工具类中的方法声明
-
静态代码段
例如,在使用数据库操作中,把和数据库的连接操作放在静态代码块中,保证一旦类工作就会先建立和数据库的连接,