文章目录
面向对象
方法
概念
一段独立的代码,能完成一件事情,可以被重复调用。
方法可以减少重复的代码。
如何调用方法
通常情况下,方法通过对象或类名使用".“操作符进行调用,也可能不用”."直接调用。
//sc就是Scanner类的一个对象
Scannser sc = new Scanner(System.in);
//通过对象sc调用Scanner类中的nextInt()方法
int inp = sc.nextInt();
//Arrays是一个类,这里通过类名调用
Arrays.sort(数组);
通过类名调用
Math类
Math类是Java提供的一个工具类,用于数学相关的运算。 其中的方法都是被static关键字修饰的静态方法,调用时,直接通过类名调用。
public class MathTest {
public static void main(String[] args) {
//绝对值
System.out.println(Math.abs(-5));
//Max
System.out.println(Math.max(1, 2));
//Min
System.out.println(Math.min(1, 2));
//pow
System.out.println(Math.pow(2, 3));
//sqrt
System.out.println(Math.sqrt(16));
//cbrt
System.out.println(Math.cbrt(8));
//ceil
System.out.println(Math.ceil(5.12));
//floor
System.out.println(Math.floor(2.12));
//round
System.out.println(Math.round(5.4));
System.out.println(Math.round(5.5));
//PI,E
System.out.println(Math.PI);
System.out.println(Math.E);
//[3~10)
System.out.println(Math.floor(Math.random() * 7 + 3));
}
}
通过对象调用
创建对象:类名 对象名 = new 类名();
//创建一个Random类的对象rd
Random rd = new Random();
//生成[0,10)范围内的随机数
int num = rd.nextInt(10);
在同一个类中,方法A调用方法B
public class FunctionTest {
public void a(){
}
public void b(){
//调用本类中的另一个方法
a();
}
}
自定义方法
自定义方法要写在类中。
访问休止符 返回值类型 方法名(参数类型 参数名 ,参数类型 参数名。。。){
方法体;
}
- 返回值类型、方法名和参数列表(小括号中的内容)是组成方法的三要素
- 返回值类型可以是任意数据类型(原始类型/引用类型)
- 小括号中的内容称为参数列表只需写参数类型和参数名,多个参数用逗号隔开。可以没有参数,但 必须要有小括号
- 访问修饰符可以不写,会有默认的修饰符
- 不同的返回值类型,要在方法体中返回(return)对应类型的结果,如果没有返回值,用void
方法的分类
- 无参无返回
//say helloworld!
void sayhelloworld() {
System.out.println("Hello World!");
}
- 无参有返回
//return helloworld!
String returnhelloworld() {
return "Hello World!";
}
- 有参无返回
//say hello
void sayhello(String name) {
System.out.println("hello," + name);
}
- 有参有返回
//return random range[int a ,int b)
int randomrane(int a, int b) {
return (int) Math.floor(Math.random() * Math.abs(a - b) + Math.min(a, b));
}
总结
-
无返回值的方法,返回值部分要写成void
-
有返回值的方法,方法体中要写上return,且要在return后写上对应返回值类型的数据
-
有返回值的的方法在调用时,需要接收返回的数据才能使用该数据
-
方法定义时的参数称为形式参数,简称为形参,方便在方法体中使用。方法调用时传递的值称为实 际参数,简称为实参,只需要保证满足形参的数据类型即可,与形参名无关
-
没有返回值的方法体中,也可以使用return关键字,但后面不能有值。只要出现return关键字,就不再执行后续代码
两种编程思想
面向过程编程
Procedure Oriented Programming 简称POP
是一种基本的编程思想,是将一件事按流程逐步实现。
这种思想强调事情完成的过程,分析步骤写出相应的代码。
如猜数游戏,每一个步骤都是能按顺序用代码描述出来,逻辑清晰。 但如果逻辑复杂,如xxx管理系统,则无法使用POP的思想实现。
C语言就是一门标志性的面向过程编程语言。
Java基础部分写的所有代码,都是面向过程的,都是一步步按流程执行。
面向对象编程
Object Oriented Programming 简称OOP
是当主流的编程思想,是创建解决问题的对象,赋予对象对应的行为和特征,让这些对象互相配合(调用 对象的方法)完成。
这种思想致力于将计算机中的世界,描述的和现实中一致的思想。
不同思想处理同一个问题
如洗衣服
POP:得到衣服、得到搓衣板、得到洗衣粉、得到水、搓洗。。。
OOP:创建一个能洗衣服的工具:洗衣机,让洗衣机拥有洗衣粉的行为(方法),调用该行为即可。 如组装电脑 POP:整理装机配置单、自己去商城购买、自己带回家、自己组装
OOP:A推荐配置单、B去商城购买、C送回家、D组装
总结
-
面向过程:亲力亲为,侧重于分析完成事情的过程。
-
面向对象:所有事情交给相应的对象完成,侧重于如何创建解决问题的对象。
类和对象
类Class
具有相同属性和行为的对象的集合,称为"一类"。可以理解为模板。
属性:描述对象的特征,在程序中,通过定义变量的形式表现属性。
行为:描述对象的动作,在程序中,通过定义方法的形式表现行为。
在程序中,通过定义一个class来定义一个类。在类中定义变量描述属性,定义方法描述行为。
定义类
[修饰符] class 类名{
//属性(变量)
//行为(方法)
}
/*
* 定义一个类(模板)--Car小轿车类
* 属性:变量
* 品牌
* 颜色
* 。。。
* 行为:方法
* 行驶
* 停止
* 娱乐
* 飞行
*/
public class Car {
//定义属性
String brand;//品牌
String color;//颜色
int seat=5;//座位数
//定义行为
void go(){
System.out.println("在行驶");
}
void stop(){
System.out.println("停下来了");
}
void fly(){
System.out.println("飞起来了");
}
}
对象Object
对象是类的一个实例,是类的具体表现。
创建对象
类名 对象名 = new 构造方法([参数]);
创建的对象,通过"."操作符访问类中的非私有属性和方法。
/*
* 创建工厂类(程序入口),该类可以创建车的对象
*/
public class Factory {
public static void main(String[] args) {
//类名 对象名 = new 类名([参数]);
//创建车类的对象c1
Car c1 = new Car();
//给对象的属性赋值
c1.brand = "宝马";
c1.color = "白色";
System.out.println("车名:" + c1.brand + ",颜色:" + c1.color + ",座位数:" + c1.seat);
c1.go();
c1.fly();
c1.stop();
Car c2 = new Car();
c2.brand = "五菱宏光";
c2.color = "黑色";
c2.seat = 7;
System.out.println("我有一辆" + c2.seat + "座的" + c2.color + c2.brand);
}
}
类和对象的关系
对象是类的具体表现,类是对象的集合(模板)。 如包饺子的模具就是一个类,每次用这个模具包出来的饺子都是一个一个对象。 先定义类,才能通过该类创建对象。
成员变量和局部变量
成员变量
定义在类中的变量,称为成员变量,拥有默认值
数据类型 | 默认值 |
---|---|
整型 | 0 |
浮点型 | 0.0 |
布尔型 | false |
字符型 | 空字符 |
引用类型(数组、类、接口) | null |
public class Car{
String brand;//这就是一个成员变量,默认值为null
void info(){
//这里brand虽然没有赋值,但是它是一个成员变量,属于引用类型,默认值为null
System.out.println("车名:"+brand);//如果不赋值,最终打印"车名:null"
}
}
局部变量
定义在方法中的变量,称为局部变量。默认有默认值,赋值后才能使用
public class Test{
public static void main(String[] args){
//这里的num和name就是一个局部变量,没有默认值
int num;
System.out.println(num);//这里无法通过编译,因为num没有赋值
String name="小明";
System.out.println(name);//这样才能正常输出
}
void sayHello(){
//这里的name也是一个局部变量
String name;
System.out.println(name);//这时也无法通过编译
}
}
成员变量局部变量面试题
-
简述成员变量和局部变量的区别以及生命周期
-
成员变量是定义在类中的变量,有默认值,不用赋值也能使用
-
局部变量是定义在方法中的变量,没有默认值,需要赋值后才能使用
-
成员变量的生命周期:类创建对象,成员变量初始化;类的对象被回收,成员变量销毁。
-
局部变量的生命周期:方法开始调用,局部变量初始化;方法调用结束,局部变量销毁。
-
构造方法
概念
构造方法是一个特殊的方法,没有返回值,方法名和类名一致。
每个类在定义时,都有一个默认隐藏的无参数的构造方法,在创建对象时调用。
构造方法通常用于初始化成员变量。
public class Test{
//这就是无参数的构造方法,默认就会存在,不过是隐藏的
public Test(){
}
}
特点
-
构造方法没有返回值(没有返回值这一部分,不是void),构造方法名必须和类名相同
-
每个类默认有一个隐藏无参数的构造方法,方法体中没有内容,用于创建无参数的对象
-
如果自己写了有参数的构造方法,默认无参数的构造方法就会失效。如果想要同时拥有带参数和不 带参数的构造方法,就需要把它们都写出来
-
构造方法可以限制创建对象时的参数
-
构造方法不能通过“.”操作符访问,只能通过new关键字创建对象时自动调用,所以构造方法通常用 于初始化成员变量
包package
通过包可以将.java源文件进行结构化管理,相当于windows中的文件夹。
不同的包中,可以保存相同名称的.java源文件。
某个类在某个包中时,会在该类的代码最上面加上 package 包名;
包的命名
包名通常使用公司域名的倒序形式。
如baidu.com公司有一个test项目,包名写为com.baidu.test。
包名中的“.”,相当于进入该文件夹,
如com.baidu.test,实际会创建3个文件夹:com下有baidu文件夹,baidu下有test文件夹
导入包
如果a包中的类要使用b包中的类时,需要在a包中的类中,导入b包。
如在使用Scanner时,就需要导入Scanner所在的java.util包。
在IDEA中,如果是通过自动补全的形式写的代码,会自动导入该类及其所在包。
如果需要手动导入包,在报错的类上按下快捷键alt+回车。
如果多个类名相同,在不同的包中,导包时需要选择合适的包。
面向对象的三大特性–封装
封装
使用private关键字对属性进行修饰。再对外提供一组公开的get/set方法用于对该属性读取或赋值。 可以防止除自身类之外的地方对该属性就行访问。
这样做可以保护关键属性,隐藏类内部的实现细节,
步骤
- 创建类,编写成员变量,给成员变量添加private修饰符
public class Student{
private int stuId;
private String stuName;
private String major;
}
- 给所有成员变量添加setXXX方法,用于给私有的成员变量赋值
public void setStuId(int stuId){
this.stuId = stuId;
}
public void setStuName(String stuName){
this.stuName = stuName;
}
public void setMajor(String major){
this.major = major;
}
- 给所有成员变量添加getXXX方法,用于读取私有的成员变量
public int getStuId(){
return stuId;
}
public String getStuName(){
return stuName;
}
public String getMajor(){
return major;
}
- 这是创建对象后,无法通过.访问属性,只能通过get/set方法
public static void main(String[] args){
Student stu = new Student();
//stu.stuId=111;无法通过.赋值和读取
//只能通过set方法赋值
stu.setStuId(10026312);
//只能通过get方法获取私有属性的值
System.out.println(stu.getStuId());
}
使用IDEA自动生成getter/setter方法
在代码空白处右键选择generate或快捷键alt+insert
Java程序运行时的内存变化
Person类
public class Person{
String name;
int age;
public Person(){
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
}
Main类
public class Main{
public static void main(String[] args){
Person p = new Person();
p.name="张敏";
p.age=22;
p = new Person("赵信",22);
}
}
面向对象三大特性–继承
继承
类A可以通过extends关键字继承类B。
语法:class 类A extends 类B{}
类A称为子类、派生类、衍生类、subClass
类B称为父类、根类、超类、superClass
继承后,子类可以访问父类中非私有(没有被private修饰的内容)的属性和方法。
不同的子类中如果有相同的代码,都可以把它们提出来保存到父类中,从而减少子类中的代码冗余。
如狗类、猫类都有类型、昵称等属性,也有吃、睡等方法,那么就可以定义一个动物类,将这些公共的 属性和方法定义在动物类中,让猫类和狗类继承动物类。
继承的特点
-
如果多个类之中有相同或类似的代码,可以将这些代码提取出来定义在一个公共的类中,这个类就 是父类。再让那些类就继承这个父类,那些类就是子类,这样就能减少子类中的重复代码
-
子类对象可以直接访问父类中非私有(不用private修饰)的属性和方法
-
子类可以对父类中的方法进行扩展或覆盖,这称为方法重写。重写后,子类对象再调用该方法时, 执行的是重写后的内容
-
Java中是单继承。一个子类只能extends一个父类,一个父类可以有很多个子类
-
Java中可以多重继承。类A可以继承类B,类B可以继承类C,这时类A既是类B的子类,也可以称为 类C的子类,可以访问类B与类C中非私有的成员
-
任何类都是Object类的子类
在创建子类对象时,会先执行父类中相应的构造方法
方法重写override
当子类继承父类后,可以对父类中非私有的方法进行扩展或覆盖,这个过程称为方法重写。
方法重写要求
-
方法名、参数列表、返回值必须和父类一致
-
访问权限不能比父类更严格(访问修饰符的范围要么一致要么更大)
-
不能抛出比父类更大的异常
方法重载overload
在一个类中,如果多个方法的方法名相同,参数列表不同时,这些方法称为重载的方法。
同名不同参。
重载用于在一个类中,某个方法在不同的条件下,执行不同的内容。
方法重载要求
-
方法名相同
-
参数列表(参数类型和数量)不同
-
与返回值无关
重载与重写相关面试题
-
说出重载与重写的异同
-
相同点:方法名不变
-
不同点:xxxx
-
-
构造方法能重载吗?能重写吗?
- 构造方法可以重载,不能重写。
-
构造方法在执行时,一定创建对象吗?
- 不一定。创建子类时会自动执行父类构造方法,但不会创建父类对象
-
以下代码执行会输出什么结果
public class Father{
public Father(){
fun();
}
public void fun(){
System.out.println("父类中的普通方法");
}
}
public class Son extends Father{
public Son(){
fun();
}
public void fun(){
System.out.println("子类中的普通方法");
}
}
public class Test{
public static void main(String[] args){
//1.创建父类对象,调用父类中的无参构造方法
//2.无参构造方法中会调用fun()方法,输出“父类中的普通方法”
new Father();
//1.创建无参子类对象,先调用父类中对应的无参构造方法
//2.父类中无参构造会调用fun()方法,实际要执行子类重写后的fun()方法,输出“子类中的普通方法”
//3.执行子类中的无参构造,调用重写后的fun()方法,输出“子类中的普通方法”
new Son();
}
}
//最终输出
父类中的普通方法
子类中的普通方法
子类中的普通方法
this和super关键字
这两个关键字,都可以当做对象使用,也可以当做构造方法使用。
当做对象使用
用法:“this.属性”或“this.方法”或“super.属性”或“super.方法”
此时的this或super表示“当前类”或"父类对象"。
public class Person{
private String name;
public void setName(String name){
this.name=name;//这里的this表示当前类Person的对象
//this表示Person p = new Person();中的p
}
public String getName(){
return name;
}
}
public class Man extends Person{
public void fun(){
System.out.println(super.getName());//这里的super表示当前类父类Person对象
//super表示Person p = new Person();中的p
}
}
当做构造方法使用
用法:“this([参数])或super([参数])”
此时的this([参数])或super([参数])表示当前类或当前类的父类的某个构造方法。
如果当做构造方法使用时,只能写在另一个构造方法中的第一行。
public class Person(){
private String name;
private int age;
public Person(){
//这句话表示调用Person(String name,int age)构造方法,只能放在第一行
this("小明",20);
}
public Person(String name,int age){
this.name=name;
this.age=age;
}
public void info(){
//this();//这里不能使用this(),因为不在构造方法中
System.out.println("我叫"+name);
}
}
public class Woman extends Person{
public Woman(String name,int age){
//这里的super()表示调用父类Person中的Person(String name,int age)构造方法
super(name,age);
}
}
注意
如果父类中有无参数的构造方法,在子类的构造方法中,可以不写super(),系统会自动调用。
如果父类中有带参数的构造方法,没有无参数的构造方法,在子类的构造方法中,必须要写super(),并 且赋予适当的参数。
- 子类和父类都不写有参数的构造方法,都用默认的无参构造方法
public class Father{
/*
默认会有
public Father(){}
*/
}
public class Son extends Father{
/*
默认会有
public Son(){
super();
}
*/
}
- 父类中没有无参数的构造方法,子类中就必须调用父类中对应的构造方法
public class Father{
private String name;
//由于该构造方法的出现,默认无参的构造方法就会失效
public Father(String name){
this.name=name;
}
}
public class Son extends Father{
public Son(String name){
//这里必须要调用父类中的构造方法,否则无法通过编译
super(name);
}
}
访问修饰符
访问修饰符可以限制某个类、属性或方法的访问权限
访问修饰符 | 含义 | 可以修饰 |
---|---|---|
public | 公共的 | 类、属性、方法 |
protected | 受保护的 | 属性、方法 |
不写 | 默认的 | 类、属性、方法 |
private | 私有的 | 属性方法 |
访问权限表
同一个类中 | 同一个包中的不同类 | 不同包中的子类 | 不同包中的非子类 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
不写 | √ | √ | × | × |
private | √ | × | × | × |
final关键字
修饰属性
当final修饰属性时,该属性的值不可更改。
定义属性时,在属性前加上final,这时的属性称为常量。常量命名时,所有字母都大写,多个单词之间 用_隔开。
final 数据类型 常量名;
final NUM = 123;
final PI = 3.14;
修饰方法
当final修饰方式时,该方法不能被重写。
定义方法时,在返回值前加上final。
public class Father{
public final void fun(){
}
}
public class Son extends Father{
//会报错,提示该方法不能被重写
@Override
public void fun(){
}
}
修饰类
当final修饰类时,该类不能被继承。
定义类时,在class前加上final。
public final class Father{
}
//会报错,提示该Father类不能被继承
public class Son extends Father{
}
Object类
是Java中所有类的父类。每个类都是这个类的子类,但没有用extends体现出来。
该类中定义了很多方法,通常需要进行重写。
常用方法 | 返回值 | 作用 |
---|---|---|
toString() | String | 在输出某个对象时,会默认调用该方法。该方法默认输出“包名. 类名@十六进制哈希码”。通常用于重写后输出对象的属性。 |
hashCode() | int | 得到某个对象的哈希码。哈希码可以理解为对象内存地址通过一 种算法转换得到的一个特定值。 |
getClass() | Class | 得到某个对象的所在类。默认输出"class 包名.类名" |
equals(Object obj) | boolean | 判断两个对象是否相同。Object中默认用==比较对象,通常需要 对其进行重写。 |
notify() | void | 唤醒某个线程 |
notifyAll() | void | 唤醒所有线程 |
wait(long time) | void | 让线程休眠,直到被唤醒 |
finalize() | void | 当某个对象被垃圾回收(GC)回收前执行的方法 |
对象造型/对象转型
类似于原始类型中的数据类型转换。对象A转换为对象B的过程称为对象造型或对象转型。
在非继承关系的两个对象中,无法实现转型。
向下转型
父类对象转换为子类对象的过程,称为向下转型。(强制转换)
转换方式:在要转换的对象前加上"(目标类型)"
//一个Object类型的对象
Object obj = new Object();
//默认无法将父类对象保存到子类变量中
//Person p = obj;
//经过向下转型即可
Person p = (Person) obj;
向上转型
子类对象转换为父类对象的过程,称为向上转型。(自动转换)
Person p = new Person();
//可以直接将子类对象保存到父类变量中
Object obj = p;
重写equals方法
在实际的业务中,如果两个对象的属性完全一致,可以视为同一个对象。
但是默认使用new创建的对象,就算属性一致,也是不同的内存地址,所以用==比较时,结果为false。
使用Object类中的equals方法比较时,默认也是用==比较,所以需要重写equals方法。
在IDEA中自动生成equals方法
在类中空白处右键 ==> generate或快捷键alt+insert==> 选择equals and hashcode ==> 选择要判断的属性。
这里可以暂时删除生成的hashcode()方法。
UserInfo类
package com.hqyj.test4;
import java.util.Objects;
/*
* 定义用户信息类
* 属性
* 用户名
* 密码
* 方法
* getter/setter
* 构造方法
* toString()
* equals()
* */
public class UserInfo {
private String username;
private String password;
/*
* 如果两个UserInfo对象的username属性一致时,视为同一个对象
* */
/*@Override
public boolean equals(Object obj) {
//如果是同一个对象,返回true
if (this == obj) {
return true;
}
//如果参数属于UserInfo类型
if (obj instanceof UserInfo) {
//将参数向下转型为UserInfo
UserInfo u = (UserInfo) obj;
//如果参数中的username与当前类的username相同
if (u.getUsername().equals(username)) {
return true;
}
}
return false;
}*/
@Override
public boolean equals(Object o) {
//如果是同一个对象,返回true
if (this == o) return true;
//如果参数为null或两个判断的对象不是同一个类型,返回false
if (o == null || getClass() != o.getClass()) return false;
//如果能执行到这里,说明两个判断的对象属于同一类型,将参数转换为UserInfo类型
UserInfo u = (UserInfo) o;
//Objects与Object不同
//Objects是一个工具类equals方法重写了Object中的equals方法,该方法的逻辑是
//先试图用==判断两个对象,如果满足返回true;再用Object中的equals方法判断,
//这时如果参数重写了equals方法,按重写的方式来(这里的u.username是一个String,就会用到String中重写的equals方法)
//如果没有重写equals方法,就按Object中的equals方法判断
return Objects.equals(username, u.username);
}
@Override
public String toString() {
return "UserInfo{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
public UserInfo(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
Main类
package com.hqyj.test4;
import java.util.Scanner;
public class Main {
//定义保存UserInfo对象的数组
UserInfo[] list = new UserInfo[10];
/*
* 注册方法
* 要求注册的用户名不能重复
* */
public boolean register(UserInfo user) {
//遍历数组检查是否已有用户
for (int i = 0; i < list.length; i++) {
if (list[i] != null && list[i].equals(user)) {
return false;
}
}
//遍历数组检查是否有空位
for (int i = 0; i < list.length; i++) {
if (list[i] == null) {
list[i] = user;
return true;
}
}
return false;
}
public void showAll() {
System.out.println("当前用户列表");
for (UserInfo userInfo : list) {
if (userInfo != null) {
//原本在没有重写toString()时,需要.getXXX输出
//现在重写了toString()方法,就可以直接输出对象,自动调用toString()
System.out.println(userInfo);
}
}
}
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
Main main = new Main();
while (true) {
System.out.println("请输入用户名");
String username = sc.next();
System.out.println("请输入密码");
String password = sc.next();
//用获取的参数创建一个UserInfo对象
UserInfo userInfo = new UserInfo(username, password);
//调用注册根据结果输出
if (main.register(userInfo)) {
System.out.println("注册成功");
} else {
System.out.println("注册失败");
}
main.showAll();
}
}
}
UserInfo类
package com.hqyj.test4;
import java.util.Objects;
/*
* 定义用户信息类
* 属性
* 用户名
* 密码
* 方法
* getter/setter
* 构造方法
* toString()
* equals()
* */
public class UserInfo {
private String username;
private String password;
/*
* 如果两个UserInfo对象的username属性一致时,视为同一个对象
* */
/*@Override
public boolean equals(Object obj) {
//如果是同一个对象,返回true
if (this == obj) {
return true;
}
//如果参数属于UserInfo类型
if (obj instanceof UserInfo) {
//将参数向下转型为UserInfo
UserInfo u = (UserInfo) obj;
//如果参数中的username与当前类的username相同
if (u.getUsername().equals(username)) {
return true;
}
}
return false;
}*/
@Override
public boolean equals(Object o) {
//如果是同一个对象,返回true
if (this == o) return true;
//如果参数为null或两个判断的对象不是同一个类型,返回false
if (o == null || getClass() != o.getClass()) return false;
//如果能执行到这里,说明两个判断的对象属于同一类型,将参数转换为UserInfo类型
UserInfo u = (UserInfo) o;
//Objects与Object不同
//Objects是一个工具类equals方法重写了Object中的equals方法,该方法的逻辑是
//先试图用==判断两个对象,如果满足返回true;再用Object中的equals方法判断,
//这时如果参数重写了equals方法,按重写的方式来(这里的u.username是一个String,就会用到String中重写的equals方法)
//如果没有重写equals方法,就按Object中的equals方法判断
return Objects.equals(username, u.username);
}
@Override
public String toString() {
return "UserInfo{" +
"username='" + username + '\'' +
", password='" + password + '\'' +
'}';
}
public UserInfo(String username, String password) {
this.username = username;
this.password = password;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
}
面向对象三大特性–多态
概念
多态就是子类的对象指向父类的引用(子类对象使用父类变量接收,即向上转型)。
父类 变量 = new 子类();
public class Father{
}
public class Son extends Father{
}
public class Main{
public static void main(String[] args){
Son son = new Son();
//这就是多态的体现
//子类的对象,可以使用父类的变量保存
Father father = new Son();
}
}
多态的应用
当某个方法的参数为父类变量时,可以传递一个子类对象。
这样就能在传递不同子类对象时,执行不同的方法。
如要调用动物发出叫声的方法,参数为猫,输出喵喵叫,参数为狗,输出汪汪叫。
不用多态,需要写多个重载的方法,参数为猫或狗的具体类型。
使用多态,只需一个方法,参数为动物类型,动物类中定义一个叫的方法,让猫和狗继承这个动物类, 重写叫的方法。
这时调用动物发出叫声的方法时,就会根据实际的参数,表示不同的结果。 多态的实现条件
多态的实现条件
- 在继承关系中
- 子类需要重写父类中的方法
- 父类的引用指向子类的对象(向上转型)
多态案例–花木兰替父从军
Woman类
package com.hqyj.test6;
/*
* 多态的应用--花木兰替父从军
* 女人类
* 继承军人类后,重写fight方法
* */
public class Woman extends Soldier {
public Woman(String name) {
super(name);
}
/*
* 化妆打扮的方法
* */
public void makeUp() {
System.out.println(super.getName() + "梳妆打扮");
}
/*
* 做家务的方法
* */
public void doHousework() {
System.out.println(super.getName() + "烧水做饭");
}
/*
*
* */
@Override
public void fight() {
System.out.println(super.getName() + "替父从军");
}
}
Soldier类
package com.hqyj.test6;
/*
* 定义军人类
* */
public class Soldier {
private String name;
public Soldier(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
/*
* 定义战斗的方法
* */
public void fight() {
System.out.println(name + "上阵杀敌");
}
}
BattleGround类
package com.hqyj.test6;
/*
* 定义战场类
* */
public class BattleGround {
/*
* 定义战争的方法,参数为一个军人对象
* */
public void war(Soldier soldier) {
soldier.fight();
}
public static void main(String[] args) {
BattleGround battleGround = new BattleGround();
//原本可以创建一个Soldier对象作为参数
Woman hua = new Woman("花木兰");
//如果创建的子类对象,用子类变量接收,可以调用子类中的方法
hua.makeUp();
hua.doHousework();
//假如不能再创建Soldier对象了
/*Soldier soldier = new Soldier("花爸爸");
battleGround.war(soldier);*/
//无法直接将Woman对象作为Soldier对象使用
//当把Woman继承Soldier类后,就能将Woman类的对象,当做Soldier使用
Soldier soldier=hua;
//如果子类的对象用父类的变量接收,无法访问子类中除父类中有的方法
// soldier.makeUp();无法调用
// soldier.doHousework();//无法调用
soldier.fight();
battleGround.war(soldier);
}
}
抽象abstract
修饰方法
使用: 访问修饰符 abstract 返回值类型 方法名(参数类型 形参名称);
如果一个方法的方法体无法描述,是由其子类进行重写,可以将该方法定义为抽象方法。
该抽象方法所在的类,也必须用abstract修饰,让其成为一个抽象类。
//当一个类中有抽象方法时,该类也需要是一个抽象类
public abstract class Game{
//这就是一个抽象方法,没有方法体
public abstract void startGame(Player player);
}
修饰类
使用: 访问修饰符 abstract class 类名{}
如果一个类中有抽象方法,这个类必须也是一个抽象类。
抽象类不能被实例化(不能创建对象)。
抽象类中,可以存在非抽象方法,如getter/setter或构造方法。
当抽象类的构造方法执行时,不会创建对象。
当一个类不希望创建它本身对象或在它其中有抽象方法时,就将该类定义为抽象类。
abstract关键字特点
修饰类:被修饰的类称为抽象类
-
抽象类不能被实例化,无法创建对象。
-
抽象类中有构造方法,在创建其子类对象时,自动调用执行。
-
抽象类中可以有抽象方法,也可以有非抽象方法。
-
抽象类的子类要么继续成为抽象类,要么重写抽象父类中的所有抽象方法。
修饰方法:被修饰的方法称为抽象方法
-
抽象方法没有方法体。
-
抽象方法只能出现在抽象类或接口中。
-
abstract不能修饰构造方法和静态方法。
抽象相关面试题
-
抽象类的特点
- 抽象类用abstract修饰,除了不能创建对象外,与普通类一样。
-
抽象方法的特点
- 抽象方法用abstract修饰,不能有方法体,非抽象子类必须要进行重写。
-
抽象类中有构造方法吗
- 有,但不是通过new该类时调用,而是在new其子类对象时调用。
-
执行某个类的构造方法时,一定会创建这个类的对象吗?
- 不一定,如果是普通类,在执行构造方法时,一定会创建对象。
- 如果是抽象类,在执行构造方法时,不会创建自身对象,只会创建其子对象。
接口interface
在Java中,数据类型分为基本类型和引用类型。
引用类型包含:数组、类和接口。
所以接口是一种数据类型,类似于类,在定义接口的时候,用interface替换class。
由于Java是单继承,如果类A既要继承类B中的内容,也要继承类C中的内容时, 如果用“extends class名”,只能选择一个类继承,但如果使用“implements interface名1,interface名 2…”,就能同时"继承"多个接口。
通常用extends表示类A继承类B,用implements表示类A实现接口A,接口B…。
接口是一个完全抽象类。一个类可以同时implements实现(“继承”)多个接口。
extends和implements
类A extends 类B
类A当做类B的子类,继承。
类A implements 接口A,接口B…
类A当做接口A、接口B的实现类(“子类”)
接口A extends 接口B
接口A通过extends继承接口B
类A extends 类B implements 接口A,接口B…
类A是类B的子类,是接口A、接口B的实现类,同时能访问这三个"父类"中的数据。
什么时候使用接口
-
如果想要让某个类作为多个"类"的子类时,将这些"父类"定义为接口
-
如果某个类中的所有方法,都是抽象方法时,可以将这个抽象类改为接口
定义接口
public interface 接口名{
//接口中只能定义公开的静态常量且要赋值,默认用public static final修饰
double PI = 3.14;
//接口中的方法默认用public abstract修饰,表示公开的抽象方法
void fun(String name);
//接口中不能定义普通方法
//void fun1(){}
//jdk1.8之后,接口中可以定义默认方法或静态方法,有方法体
default void fun2(){
}
static void fun3(){
}
}
接口的特点
-
接口中的属性默认被public static final修饰,表示公共的静态常量,需要赋值。使用时直接通过类 名访问。
-
接口中的方法默认被public abstract修饰,表示公共的抽象方法,没有方法体。
-
JDK1.8后,接口中可以存在两种特殊的方法,都有方法体
-
被default修饰的默认方法
-
被static修饰的静态方法
-
-
-
接口中没有构造方法,不能创建对象。
-
接口通常需要子类实现,实现后必须重写其中的所有抽象方法。
接口应用案例
模拟电脑使用USB设备
USB接口
package com.hqyj.test4;
/*
* 定义USB接口,模拟电脑开机,运行各种USB设备
*
* */
public interface USB {
/*
* 任何USB类型的设备,都需要开启和关闭的方法
* */
void start();
void stop();
}
Computer类
package com.hqyj.test4;
/*
* 定义电脑类
* */
public class Computer {
/*
* 开机的方法,参数为USB设备,调用USB参数的开启的方法
* */
public void powerOn(USB usb1, USB usb2) {
System.out.println("电脑开机。。");
if (usb1 != null) {
usb1.start();
} else {
System.out.println("当前USB1插槽没有设备");
}
if (usb2 != null) {
usb2.start();
} else {
System.out.println("当前USB2插槽没有设备");
}
}
/*
* 关机的方法,参数为USB设备,调用USB参数的关闭的方法
* */
public void powerOff(USB usb1, USB usb2) {
System.out.println("电脑关机。。");
usb1.stop();
usb2.stop();
}
}
USB接口实现类–Mouse类
package com.hqyj.test4;
public class Mouse implements USB {
private String name;
public Mouse(String name) {
this.name = name;
}
@Override
public void start() {
System.out.println(name + "鼠标正在启动");
}
@Override
public void stop() {
System.out.println(name + "鼠标正在停止");
}
}
USB接口实现类–Keyboard类
package com.hqyj.test4;
/*
* USB接口实现类--键盘类
* */
public class Keyboard implements USB {
private String name;
private int keysNum;
public Keyboard(String name, int keysNum) {
this.name = name;
this.keysNum = keysNum;
}
@Override
public void start() {
System.out.println(keysNum + "键的" + name + "键盘正在启动");
}
@Override
public void stop() {
System.out.println(keysNum + "键的" + name + "键盘正在关闭");
}
}
main方法所在类
package com.hqyj.test4;
public class Main {
public static void main(String[] args) {
Computer computer = new Computer();
//可以使用接口变量接收实现类对象
// USB keyboard=new Keyboard("罗技K845",104);
Keyboard keyboard = new Keyboard("罗技K845", 104);
USB mouse = new Mouse("GPW");
//调用开机关机的方法
computer.powerOn(keyboard, mouse);
computer.powerOff(keyboard,mouse);
}
}
抽象类和接口的异同
- 抽象类是一个类,用abstract class定义
- 有构造方法,不能创建对象,在创建子类对象时调用构造方法
- 抽象类中可以有抽象方法,也可以有普通方法
- 抽象类被子类继承时,使用extends关键字。子类必须重写父类中的所有抽象方法
- 子类只能继承一个抽象类
- 接口不是一个类,用interface定义
- 没有构造方法,不能创建对象
- 接口中的属性都是公共的静态常量
- 接口中的方法都是公共的抽象方法
- JDK1.8后,可以在接口中定义default方法和static方法
- 接口被实现类实现时,使用implements关键字。实现类必须重写父接口中的所有抽象方法
- 实现类可以实现多个接口
- 相同点
- 接口和抽象类都不能创建对象
- 接口的实现类和抽象类的子类,都需要重写抽象方法
创建对象时的内存变化
每次new一个对象,都会在堆空间中开辟一块区域,这个过程是需要花费时间和空间的。
在栈空间中,只会定义变量,保存堆空间某块区域的地址。通过变量相当于直接访问堆空间中的某个地 址中对应的数据。
如果多个对象都有相同的属性或方法时,可以将这些共用的属性和方法使用static修饰后,保存到静态区中。
如上图中的"长江师范学院"这个字符串,每个对象都会用,就可以将该对象用static定义为静态属性。
静态属性或静态方法,会脱离对象存在,在类加载的时候就保存到内存中。
static静态的
static是一个修饰符,可以修饰属性、方法、代码块。
被static修饰的内容,称为静态成员。静态成员在类加载的时候,就会保存到内存中,可以脱离对象存在。
所以访问静态成员时,可以不用创建对象,直接通过类名访问。如Math中的属性和方法都是静态的,所以直接通过Math访问。
什么时候使用static
如果某个属性或方法被高度重用时,可以将其定义为static静态的。
这样这些属性就会脱离对象,在类加载时就加载到内存中,从而直接通过类名即可访问。
或不想创建对象就想使用该类中的属性或方法时,将它们定义为静态的。
如何访问静态成员
直接通过类名就能访问静态成员。也可以通过对象访问。
静态常量
static修饰属性时,通常和final一起使用,表示静态常量
public class Person{
//静态常量
public final static String COUNTRY="中华人民共和国";
}
public class Test{
public static void main(String[] arg){
//静态成员直接通过类名访问
System.out.println(Person.COUNTRY);
}
}
静态方法
public class Person{
public final static String COUNTRY="中华人民共和国";
//静态方法
public static void info(){
System.out.println("我来自于"+COUNTRY);
}
}
public class Test{
public static void main(String[] arg){
//静态成员直接通过类名访问
Person.info();
}
}
静态代码块
public class Person{
//静态代码块
static {
//这里的代码在类加载时自动执行。
}
}
static特点
- 静态方法中只能使用静态成员,不能使用非静态成员
public class Student{
static String str="静态成员变量";
int num=123;//非静态成员变量
//静态方法中只能使用静态成员
public static void fun(){
System.out.println(str);//可以
//System.out.println(num);报错
}
}
- 非静态方法中可以使用静态成员
public class Student{
static String str="静态成员变量";
int num=123;//非静态成员变量
//非静态方法中可以使用静态成员
public void fun2(){
System.out.println(str);//可以
System.out.println(num);//可以
}
}
- 静态方法中不能使用this关键字
成员变量、局部变量、静态常量
成员变量:定义在类中的变量
成员变量随着对象的创建而存在,随着对象的回收而销毁。作用范围在类内部。成员变量有初始值。
局部变量:定义在方法中的变量
局部变量随着方法的调用而存在,随着方法执行结束而销毁。作用范围在方法内部。
静态常量:被final、static修饰的成员变量
静态常量随着类的加载而存在,随着类的销毁而销毁。作为范围在程序运行周期中。静态常量有初始值。
public class Animal{
//静态常量
public static final String ZOO="重庆动物园";
//成员变量
private String type;
//静态成员方法
public static void welcome(){
System.out.println("欢迎光临"+ZOO);
}
//成员方法
public void info(){
//局部变量
String str="你好";
System.out.println(ZOO+"中的"+type+"在打招呼说"+str);
}
}
可变参数
当某个方法的参数是同一类型且数量未知时,使用可变参数定义。
语法
修饰符 返回类型 方法名 (数据类型。。。 形参){
//这时的参数数量时可变的,范围[0,无穷)
//整个参数会成为一个数组
}
特点
- 可变参数只能在方法列表中出现一次,且是最后一个参数
- 可变参数实际是一个数组
- 调用方法时,传递的实参需要用逗号隔开
举例
Function.java
package Phone;
public interface Function {
void ShowFunctionInfo();
}
Camera.java
package Phone;
public class Camera implements Function {
private String cameraBrand;
private long cameraPX;
public String getCameraBrand() {
return cameraBrand;
}
public void setCameraBrand(String cameraBrand) {
this.cameraBrand = cameraBrand;
}
public long getCameraPX() {
return cameraPX;
}
public void setCameraPX(long cameraPX) {
this.cameraPX = cameraPX;
}
public Camera(String cameraBrand, long cameraPX) {
this.cameraBrand = cameraBrand;
this.cameraPX = cameraPX;
}
@Override
public String toString() {
return "Camera{" +
"cameraBrand='" + cameraBrand + '\'' +
", cameraPX=" + cameraPX +
'}';
}
@Override
public void ShowFunctionInfo() {
System.out.println(this.toString());
}
}
PhoneTest.java
package Phone;
public class PhoneTest {
String phoneBrand;
public PhoneTest(String phoneBrand) {
this.phoneBrand = phoneBrand;
}
@Override
public String toString() {
return "PhoneTest{" +
"phoneBrand='" + phoneBrand + '\'' +
'}';
}
//可变参数的使用
void ShowPhoneInfo(Function... functions) {
System.out.println(this.toString());
for (Function function : functions) {
function.ShowFunctionInfo();
}
}
public static void main(String[] args) {
PhoneTest phoneTest = new PhoneTest("水果");
Camera camera = new Camera("徕卡", 100);
Camera camera1 = new Camera("蔡司", 200);
phoneTest.ShowPhoneInfo(camera, camera1);
}
}
枚举enum
Java中的枚举时一个特殊的类,时一些常量的集合。
定义枚举类型
public enum 枚举类型{
常量1,常量2。。。常量n
}
案例-定义枚举类型Week
public eenum enum{
SUN,MON,TUE, WED, THU, FRI, SAT
}
package EnumTest;
public class MainTest {
public static void main(String[] args) {
for (enumTest value : enumTest.values()) {
System.out.println(value);
}
System.out.println(enumTest.valueOf("S"));
}
}
内部类
内部类,时只定义在类中的类。
内部类可以隐藏某个类的实现细节,将类进行封装。
内部类分为成员内部类、静态内部类、局部内部类和匿名类。这里只说明匿名内部类。
匿名内部类
当某个方法的参数为接口类型时,通常会先定义该接口的实现类,再创建实现类的对象作为方法的参数。
在使用匿名内部类后,就可以不要创建实现类,而是直接通过匿名内部类作为参数使用。
举例
USB接口
public interface USB{
void start();
}
Computer类
public class Computer{
public void poweron(USB... usbs){
for(USB : usbs){
u.start();
}
}
}
通常情况下,需要创建一个USB接口的实现类-Keyboard键盘类
public class Keyboard implements USB{
public void start(){
System.out.println("键盘设备接入");
}
}
在main方法中,需要用到USB接口参数时,传递一个USB接口的实现类对象
public class Test{
public static void main(String[] args){
Computer com = new Computer();
//poweron()方法的参数为USB接口类型的变量,这里poweron()方法中的大括号{}整体是一个匿名内部类,即USB接口的“实现类”
com.poweron(new USB(){
public void start(){
System.out.println("某USB设备接入");
}
});
}
}
学习中的sample
模拟“电子宠物”
进入系统,创建宠物(可以手动创建,也可以自动随机创建)
如果手动创建,就输入宠物信息:品种、昵称
进入菜单
1.查看宠物信息
打印我叫xxx,是一只xxx,是您的电子宠物
2.喂食
接收输入的食物名,输出xxx正在吃xxx
3.玩耍
接收输入的玩具名,输出xxx正在玩耍xxx
宠物类
属性:品种、昵称
方法:输出信息、喂食(String 食物){}、玩耍(String 玩具){}
Main类
main(){
打印菜单,输入选项
}
ElectronicPetTest.java
package ElectronicPet;
import java.util.Random;
import java.util.Scanner;
public class ElectronicPetTest {
public static void main(String[] args) throws InterruptedException {
Scanner sc = new Scanner(System.in);
/**
* 领养宠物
* 1.手动
* 2.随机
*
* 手动
* 选种类
* 取名字
*
* 自动
* 随机种类
* 取名字
*
* 互动
* 1.查看信息
* 2.唱歌
* 3.吃饭
*
*/
//0 猫头鹰 1 兔子 2 蝎子
String[] petBreedArr = {"猫头鹰", "兔子", "蝎子"};
String[] petPhotoArr = {" ,___, \n" +
" (9v9) \n" +
" (_^((\\ \n" +
" ^^^\"^\" \\\\^^^^\n" +
" ^^^^^^^^^^^^^", " ,-.,-. \\n\" +\n" +
" \" ( ( ( \\n\" +\n" +
" \" \\\\ ) ) _..-.._ \\n\" +\n" +
" \" __)/ ,’,’ `.\\n\" +\n" +
" \" ,' `. ,--. `. \\n\" +\n" +
" \" ,' @ .’ ` \\\\\\n\" +\n" +
" \" (Y ( ;’’.\\n\" +\n" +
" \" `--.____, \\\\ , ; \\n\" +\n" +
" \" ((_ ,----’ ,---’ _,’_,’ \\n\" +\n" +
" \" (((_,- (((______,-’", " ___ __\n" +
" _{___{__}\\\n" +
" {_} `\\) \n" +
" {_} ` _.-''''--.._\n" +
" {_} //'.--. \\___`.\n" +
" { }__,_.--~~~-~~~-~~-::.---. `-.\\ `.)\n" +
" `-.{_{_{_{_{_{_{_{_// -- 8;=- `\n" +
" `-:,_.:,_:,_:,.`\\\\._ ..'=- ,\n" +
" // // // //`-.`\\` .-'/\n" +
" << << << << \\ `--' /----)\n" +
" ^ ^ ^ ^ `-.....--'''"};
System.out.print("请选择你要领养的宠物:\n1.猫头鹰\n2.兔子\n3.蝎子\n4.随机\n你的选择是:");
Integer petSelect = sc.nextInt();
Integer petBreed = 0;
switch (petSelect) {
case 1:
petBreed = 0;
break;
case 2:
petBreed = 1;
break;
case 3:
petBreed = 2;
break;
case 4:
Random rd = new Random();
petBreed = rd.nextInt(3);
}
System.out.print("\n请给它命名吧!名字:");
String petName = sc.next();
Pet pet = new Pet(petName, petBreedArr[petBreed]);
boolean flag = true;
while (flag) {
System.out.print("\n互动:\n1.吃饭\n2.唱歌\n3.退出互动\n4.查看宠物\n选择:");
switch (sc.nextInt()) {
case 1:
System.out.print("\n给宠物吃什么:");
pet.eatFood(sc.next());
break;
case 2:
System.out.print("\n唱什么歌呢:");
pet.sing(sc.next());
break;
case 3:
System.out.println("要记得我哦!");
flag = false;
break;
case 4:
System.out.println(petPhotoArr[petBreed]);
System.out.println("我的名字叫:" + pet.petName);
break;
}
}
}
}
Pet.java
package ElectronicPet;
/**
* 电子宠物:
* 名字
* 年龄
* 性别
* 种族
* 图片
* 等级
* 攻击力
* 生命值100
* 饱食度100
* 心情100
* 主人
*/
public class Pet {
String petName;
String petBreed;
int petGrade = 0;
int petHealth = 100;
int petHungerValue = 100;
int petMood = 100;
public Pet(String petName, String petBreed) {
this.petName = petName;
this.petBreed = petBreed;
}
//eat
void eatFood(String food) throws InterruptedException {
System.out.println(this.petName + "正在食用" + food);
for (int i = 0; i < 5; i++) {
Thread.sleep(300);
System.out.print("吭哧~~");
}
System.out.print("吃完了!\n饱食度+20!!\n");
petHungerValue += 20;
if (petHungerValue > 100) petHungerValue = 100;
}
//sing
void sing(String song) throws InterruptedException {
System.out.println(this.petName + "正在歌唱" + song);
for (int i = 0; i < 5; i++) {
Thread.sleep(300);
System.out.print("啦啦~~");
}
System.out.print("唱完了!\n心情+20!!\n");
petMood += 20;
if (petMood > 100) petMood = 100;
}
}
效果
使用面向对象思想实现简易图书管理系统
图书类
-
属性
-
编号
-
书名
-
作者
-
价格
-
图书管理员类
-
属性
-
用户名
-
密码
-
图书数组
-
-
方法
-
添加
-
查看
-
修改
-
删除
-
Book.java
package LibraryManagementSystem;
/**
* 图书
* 编号
* 名字
* 价格
* 作者
* 方法:
* 打印信息
*/
public class Book {
private long bookId;
private String bookName;
private float bookPrice;
private String bookAuthor;
private String[] bookInfoArr = {"编号", "名字", "价格", "作者"};
public String[] getBookInfoArr() {
return bookInfoArr;
}
public void setBookInfoArr(String[] bookInfoArr) {
this.bookInfoArr = bookInfoArr;
}
public long getBookId() {
return bookId;
}
public void setBookId(long bookId) {
this.bookId = bookId;
}
public String getBookName() {
return bookName;
}
public void setBookName(String bookName) {
this.bookName = bookName;
}
public float getBookPrice() {
return bookPrice;
}
public void setBookPrice(float bookPrice) {
this.bookPrice = bookPrice;
}
public String getBookAuthor() {
return bookAuthor;
}
public void setBookAuthor(String bookAuthor) {
this.bookAuthor = bookAuthor;
}
public Book() {
}
public Book(long bookId, String bookName, float bookPrice, String bookAuthor) {
this.bookId = bookId;
this.bookName = bookName;
this.bookPrice = bookPrice;
this.bookAuthor = bookAuthor;
}
public void PrintBookInfo() {
System.out.println("===================");
System.out.println("编号:" + bookId);
System.out.println("书名:" + bookName);
System.out.println("价格:" + bookPrice);
System.out.println("作者:" + bookAuthor);
}
}
ManagementSystemUser.java
package LibraryManagementSystem;
/**
* 用户
* 账号
* 密码
* 等级
*/
public class ManagementSystemUser {
private String managementSystemUserId;
private String managementSystemUserPwd;
private int managementSystemUserGrade;
private String[] managementSystemUserTerm = {"用户名", "用户密码", "用户组"};
public String[] getManagementSystemUserTerm() {
return managementSystemUserTerm;
}
public void setManagementSystemUserTerm(String[] managementSystemUserTerm) {
this.managementSystemUserTerm = managementSystemUserTerm;
}
public String getManagementSystemUserId() {
return managementSystemUserId;
}
public void setManagementSystemUserId(String managementSystemUserId) {
this.managementSystemUserId = managementSystemUserId;
}
public String getManagementSystemUserPwd() {
return managementSystemUserPwd;
}
public void setManagementSystemUserPwd(String managementSystemUserPwd) {
this.managementSystemUserPwd = managementSystemUserPwd;
}
public int getManagementSystemUserGrade() {
return managementSystemUserGrade;
}
public void setManagementSystemUserGrade(int managementSystemUserGrade) {
this.managementSystemUserGrade = managementSystemUserGrade;
}
public ManagementSystemUser(String managementSystemUserId, String managementSystemUserPwd, int managementSystemUserGrade) {
this.managementSystemUserId = managementSystemUserId;
this.managementSystemUserPwd = managementSystemUserPwd;
this.managementSystemUserGrade = managementSystemUserGrade;
}
void PrintManagementSystemUserInfo() {
System.out.println("用户名:" + managementSystemUserId);
System.out.println("用户密码:" + managementSystemUserPwd);
System.out.println("用户组:" + managementSystemUserGrade);
}
}
ManagementSystem.java
package LibraryManagementSystem;
import java.util.Scanner;
/**
* 管理系统
* 版本号
* 登录注册用户组
* 用户组数组
* 图书数组
* 区分用户组
* 管理员:增删改查
* 成员:查
* 方法:
* 对图书的增删改查
*/
public class ManagementSystem {
private int versionNo;
private ManagementSystemUser[] managementSystemUserArr;
private Book[] bookArr;
public int getVersionNo() {
return versionNo;
}
public void setVersionNo(int versionNo) {
this.versionNo = versionNo;
}
public ManagementSystem() {
Scanner sc = new Scanner(System.in);
System.out.print("初始化软件:\n设置用户规模:");
managementSystemUserArr = new ManagementSystemUser[sc.nextInt()];
System.out.print("设置图书规模:");
bookArr = new Book[sc.nextInt()];
boolean flag = true;
//循环功能
while (flag) {
System.out.print("==========\n1.登录\n2.注册\n3.退出\n选择:");
switch (sc.nextInt()) {
//登录
case 1:
System.out.print("用户名:");
String loginId = sc.next();
System.out.print("密码:");
String loginPwd = sc.next();
//登录
if (UserLogin(loginId, loginPwd) != -1) {
//区分用户组,成员
if (managementSystemUserArr[ManagementSystemUserFindById(loginId)].getManagementSystemUserGrade() == 1) {
System.out.println("Welcome!");
boolean flag1 = true;
//循环功能
while (flag1) {
System.out.print("===================\n1.查看所有书籍\n2.搜索书籍\n3.退出\n选择:");
switch (sc.nextInt()) {
case 1:
ViewAllBookInfo();
break;
case 2:
SearchDeleteUpdateBookInfoUtil(2);
break;
case 3:
flag1 = false;
break;
}
}//区分用户组,管理员
} else if (managementSystemUserArr[ManagementSystemUserFindById(loginId)].getManagementSystemUserGrade() == 0) {
System.out.println("Welcome!Admin!");
boolean flag2 = true;
//循环功能
while (flag2) {
System.out.print("===================\n1.查看所有书籍\n2.搜索书籍\n3.增加书籍\n4.删除书籍\n5.修改书籍\n6.退出\n选择:");
switch (sc.nextInt()) {
case 1:
ViewAllBookInfo();
break;
case 2:
SearchDeleteUpdateBookInfoUtil(2);
break;
case 3:
//循环输入书籍信息
Book book = new Book();
String[] bookInfoTerm = book.getBookInfoArr();
String[] bookInfoTermNull = new String[book.getBookInfoArr().length];
for (int i = 0; i < bookInfoTerm.length; i++) {
System.out.print("请输入书籍" + bookInfoTerm[i] + ":");
bookInfoTermNull[i] = sc.next();
}
//没有异常就添加-1:重复 -2:满员
if (AddBookInfo(Long.parseLong(bookInfoTermNull[0]), bookInfoTermNull[1], Float.parseFloat(bookInfoTermNull[2]), bookInfoTermNull[3]) != -1 && AddBookInfo(Long.parseLong(bookInfoTermNull[0]), bookInfoTermNull[1], Float.parseFloat(bookInfoTermNull[2]), bookInfoTermNull[3]) != -2) {
System.out.println("添加成功!");
} else if (AddBookInfo(Long.parseLong(bookInfoTermNull[0]), bookInfoTermNull[1], Float.parseFloat(bookInfoTermNull[2]), bookInfoTermNull[3]) == -1 || AddBookInfo(Long.parseLong(bookInfoTermNull[0]), bookInfoTermNull[1], Float.parseFloat(bookInfoTermNull[2]), bookInfoTermNull[3]) == -2) {
System.out.println("重复或满员!");
}
break;
case 4:
SearchDeleteUpdateBookInfoUtil(1);
break;
case 5:
SearchDeleteUpdateBookInfoUtil(3);
break;
case 6:
flag2 = false;
break;
}
}
}
} else {
System.out.println("用户名或密码错误!");
}
break;
//注册
case 2:
System.out.println("1.成员\n2.管理员");
switch (sc.nextInt()) {
//成员注册
case 1:
System.out.print("用户名:");
String registerId = sc.next();
System.out.print("密码:");
String registerPwd = sc.next();
//没有异常就添加-1:重复 -2:满员
if (UserRegister(registerId, registerPwd, 1) != -1 && UserRegister(registerId, registerPwd, 1) != -2) {
System.out.println("yes");
} else if (UserRegister(registerId, registerPwd, 1) == -1 || UserRegister(registerId, registerPwd, 1) == -2)
System.out.println("重复或满员!");
break;
//管理员注册
case 2:
//密匙就是版本号
System.out.print("软件密匙:");
if (sc.nextInt() == versionNo) {
System.out.print("用户名:");
String registerAdminId = sc.next();
System.out.print("密码:");
String registerAdminPwd = sc.next();
//没有异常就添加-1:重复 -2:满员
if (UserRegister(registerAdminId, registerAdminPwd, 0) != -1 && UserRegister(registerAdminId, registerAdminPwd, 0) != -2) {
System.out.println("yes!Admin!");
} else if (UserRegister(registerAdminId, registerAdminPwd, 0) == -1 || UserRegister(registerAdminId, registerAdminPwd, 0) == -2)
System.out.println("重复或满员!");
} else {
System.out.println("联系厂商!");
}
break;
}
break;
//退出
case 3:
flag = false;
break;
}
}
}
//UserRegister
int UserRegister(String registerId, String registerPwd, int registerGrade) {
int a = -1;//-1:重复
int id = ManagementSystemUserFindById(registerId);
//没有重复执行
if (id == -1) {
//找空位
int nullId = ManagementSystemUserFindByNull();
//有空位
if (nullId != -1) {
//添加
managementSystemUserArr[nullId] = new ManagementSystemUser(registerId, registerPwd, registerGrade);
a = nullId;
} else a = -2;//满员
}
return a;
}
//UserLogin
int UserLogin(String loginId, String loginPwd) {
//-1:登录失败
int a = -1;
//循环匹配用户名和密码
for (int i = 0; i < managementSystemUserArr.length; i++) {
//空对象跳过
if (managementSystemUserArr[i] == null) continue;
if (managementSystemUserArr[i].getManagementSystemUserId().equals(loginId) && managementSystemUserArr[i].getManagementSystemUserPwd().equals(loginPwd)) {
//匹配成功,登录
a = i;
}
}
return a;
}
//ManagementSystemUserFindByNull
int ManagementSystemUserFindByNull() {
//-1:匹配空位失败,满员
int a = -1;
//循环匹配空位
for (int i = 0; i < managementSystemUserArr.length; i++) {
if (managementSystemUserArr[i] == null) {
//匹配成功,返回位置
a = i;
break;
}
}
return a;
}
//ManagementSystemUserFindById
int ManagementSystemUserFindById(String findId) {
//-1:未找到Id
int a = -1;
//循环匹配Id
for (int i = 0; i < managementSystemUserArr.length; i++) {
//空对象跳过
if (managementSystemUserArr[i] == null) continue;
if (managementSystemUserArr[i].getManagementSystemUserId().equals(findId)) {
//匹配到Id,返回
a = i;
}
}
return a;
}
//BookFindByNull
int BookFindByNull() {
int a = -1;
for (int i = 0; i < bookArr.length; i++) {
if (bookArr[i] == null) {
a = i;
break;
}
}
return a;
}
//BookFindById
int BookFindById(long findId) {
int a = -1;
for (int i = 0; i < bookArr.length; i++) {
if (bookArr[i] == null) continue;
if (bookArr[i].getBookId() == findId) {
a = i;
}
}
return a;
}
//ViewAllBookInfo
void ViewAllBookInfo() {
//循环打印
for (int i = 0; i < bookArr.length; i++) {
if (bookArr[i] == null) continue;
bookArr[i].PrintBookInfo();
}
}
//AddBookInfo
int AddBookInfo(long bookId, String bookName, float bookPrice, String bookAuthor) {
int a = -1;
if (BookFindById(bookId) == -1) {
int addBookId = BookFindByNull();
if (addBookId != -1) {
a = addBookId;
bookArr[addBookId] = new Book(bookId, bookName, bookPrice, bookAuthor);
} else a = -2;//满了
}
return a;
}
//SearchBookInfo
int SearchBookInfo(long searchId) {
int a = -1;
int findId = BookFindById(searchId);
if (findId != -1) {
a = findId;
}
return a;
}
//SearchDeleteUpdateBookInfoUtil
void SearchDeleteUpdateBookInfoUtil(int i) {
//三个功能都要查Id
Scanner sc = new Scanner(System.in);
System.out.print("输入书籍编号:");
int searchDeleteUpdateId = SearchBookInfo(sc.nextInt());
//查到了
if (searchDeleteUpdateId != -1) {
switch (i) {
//delete
case 1:
bookArr[searchDeleteUpdateId] = null;
System.out.println("删除成功!");
break;
//search
case 2:
bookArr[searchDeleteUpdateId].PrintBookInfo();
break;
//update
case 3:
boolean flag = true;
//循环修改
while (flag) {
//显示信息
bookArr[searchDeleteUpdateId].PrintBookInfo();
System.out.print("===================\n修改:\n0.退出\n1.名字\n2.价格\n3.作者\n选择:");
switch (sc.nextInt()) {
case 0:
flag = false;
break;
case 1:
System.out.print("输入名字:");
UpdateBookInfoTerm(searchDeleteUpdateId, 1, sc.next());
break;
case 2:
System.out.print("输入价格:");
UpdateBookInfoTerm(searchDeleteUpdateId, 2, sc.next());
break;
case 3:
System.out.print("输入作者:");
UpdateBookInfoTerm(searchDeleteUpdateId, 3, sc.next());
break;
}
}
}
} else System.out.println("查无此书!");
}
//UpdateBookInfoTerm
int UpdateBookInfoTerm(int updateBookId, int updateBookInfoTerm, String updateBookInfoValue) {
int a = -1;
switch (updateBookInfoTerm) {
case 1:
bookArr[updateBookId].setBookName(updateBookInfoValue);
a = 1;
break;
case 2:
bookArr[updateBookId].setBookPrice(Float.parseFloat(updateBookInfoValue));
a = 2;
break;
case 3:
bookArr[updateBookId].setBookAuthor(updateBookInfoValue);
a = 3;
break;
}
return a;
}
}
Test.java
package LibraryManagementSystem;
public class Test {
public static void main(String[] args) {
ManagementSystem ms = new ManagementSystem();
}
}
1.登录注册
2.添加书籍
3.修改书籍
模拟游戏角色PK
游戏角色类
属性:姓名、阵营、武器、技能、生命值
玩家类
属性:保存游戏角色的数组
方法:添加角色、查看所有、根据编号得到角色、战斗
根据编号得到角色方法(编号){
//用1开始当编号
return 数组[编号-1]
}
战斗方法(角色1,角色2){
/*
4 5 6 7 8 9 10 11 12随机数
3的倍数 6 9 12 角色1发动技能
4的倍数 4 8 12 角色2发动技能
12双方发动技能
其余数字普通攻击
一方血量低于0停止
*/
}
Character.java
package ApexPK;
/**
* 角色
* 名字
* 武器
* 技能
* 生命
*/
public class Character {
private long characterId;
private String characterName;
private Arms characterArms;
private Skill characterSkill;
private int characterHP;
public Character(long characterId, String characterName, Arms characterArms, Skill characterSkill, int characterHP) {
this.characterId = characterId;
this.characterName = characterName;
this.characterArms = characterArms;
this.characterSkill = characterSkill;
this.characterHP = characterHP;
}
public long getCharacterId() {
return characterId;
}
public void setCharacterId(long characterId) {
this.characterId = characterId;
}
public String getCharacterName() {
return characterName;
}
public void setCharacterName(String characterName) {
this.characterName = characterName;
}
public Arms getCharacterArms() {
return characterArms;
}
public void setCharacterArms(Arms characterArms) {
this.characterArms = characterArms;
}
public Skill getCharacterSkill() {
return characterSkill;
}
public void setCharacterSkill(Skill characterSkill) {
this.characterSkill = characterSkill;
}
public int getCharacterHP() {
return characterHP;
}
public void setCharacterHP(int characterHP) {
this.characterHP = characterHP;
}
}
CharacterManager.java
package ApexPK;
/**
* Character管理类
*/
public class CharacterManager {
private Character[] characterArr;
public Character[] getCharacterArr() {
return characterArr;
}
public void setCharacterArr(int characterArrNumber) {
characterArr = new Character[characterArrNumber];
characterArr[0] = new Character(1000, "科学妈妈", new Arms("R-99", 15), new Skill("黑洞", 100), 1000);
characterArr[1] = new Character(1001, "高科技电子追踪犬", new Arms("R-301", 25), new Skill("扫描", 50), 1000);
characterArr[2] = new Character(1002, "机器人", new Arms("L-Star", 20), new Skill("钩爪", 65), 1000);
}
//AddCharacter
public int AddCharacter(Character character) {
//-1:重复
int a = -1;
int characterArrId = FindByCharacterId(character);
if (characterArrId == -1) {
int characterArrNull = FindByNull();
//有位置
if (characterArrNull != -1) {
characterArr[characterArrNull] = character;
a = characterArrNull;
} else a = -2;//-2:没位置
}
return a;
}
//DeleteCharacter
public int DeleteCharacter(Character character) {
//-1:无人
int a = -1;
int deleteCharacterArrId = FindByCharacterId(character);
if (deleteCharacterArrId != -1) {
characterArr[deleteCharacterArrId] = null;
a = deleteCharacterArrId;
}
return a;
}
//UpdateCharacter
public int UpdateCharacter(Character character, int switchField, Object updateValue) {
int a = -1;
int updateCharacterArr = FindByCharacterId(character);
switch (switchField) {
//名字
case 1:
characterArr[updateCharacterArr].setCharacterName((String) updateValue);
a = 1;
break;
//武器
case 2:
characterArr[updateCharacterArr].setCharacterArms((Arms) updateValue);
a = 2;
break;
//技能
case 3:
characterArr[updateCharacterArr].setCharacterSkill((Skill) updateValue);
a = 3;
break;
//生命值
case 4:
characterArr[updateCharacterArr].setCharacterHP(Integer.parseInt((String) updateValue));
a = 4;
break;
}
return a;
}
//FindByCharacterId
public int FindByCharacterId(Character character) {
//-1:未找到
int a = -1;
for (int i = 0; i < characterArr.length; i++) {
if (characterArr[i] == null) continue;
if (characterArr[i].getCharacterId() == character.getCharacterId()) {
a = i;
}
}
return a;
}
//FindByCharacter(Character)
public Character FindByCharacter(Character character) {
Character findCharacter = null;
for (int i = 0; i < characterArr.length; i++) {
if (characterArr[i] == null) continue;
if (characterArr[i].getCharacterId() == character.getCharacterId()) {
findCharacter = characterArr[i];
}
}
return findCharacter;
}
//FindByNull
public int FindByNull() {
//-1:满员
int a = -1;
for (int i = 0; i < characterArr.length; i++) {
if (characterArr[i] == null) {
a = i;
}
}
return a;
}
//ViewAllCharacter
public void ViewAllCharacter() {
System.out.println("======================================================");
System.out.println("编号\t名字\t武器:攻击力\t技能:攻击力\t生命值");
for (Character character : characterArr) {
if (character == null) continue;
ViewSingleCharacter(character, false);
}
}
//ViewSingleCharacter
public void ViewSingleCharacter(Character character, boolean showField) {
System.out.println("======================================================");
if (showField) {
System.out.println("编号\t名字\t武器:攻击力\t技能:攻击力\t生命值");
}
System.out.println(character.getCharacterId() + "\t" + character.getCharacterName() + "\t" + character.getCharacterArms().getArmsName() + ":" + character.getCharacterArms().getArmsATK() + "\t" + character.getCharacterSkill().getSkillName() + ":" + character.getCharacterSkill().getSkillATK() + "\t" + character.getCharacterHP());
}
}
Arms.java
package ApexPK;
/**
* 武器
* 1.名字
* 2.攻击力
*/
public class Arms {
private String armsName;
private int armsATK;
public Arms(String armsName, int armsATK) {
this.armsName = armsName;
this.armsATK = armsATK;
}
public String getArmsName() {
return armsName;
}
public void setArmsName(String armsName) {
this.armsName = armsName;
}
public int getArmsATK() {
return armsATK;
}
public void setArmsATK(int armsATK) {
this.armsATK = armsATK;
}
}
Skill.java
package ApexPK;
/**
* 技能
* 1.名字
* 2.攻击力
*/
public class Skill extends Object {
private String skillName;
private int skillATK;
public Skill(String skillName, int skillATK) {
this.skillName = skillName;
this.skillATK = skillATK;
}
public String getSkillName() {
return skillName;
}
public void setSkillName(String skillName) {
this.skillName = skillName;
}
public int getSkillATK() {
return skillATK;
}
public void setSkillATK(int skillATK) {
this.skillATK = skillATK;
}
}
Main.java
package ApexPK;
import java.util.Random;
import java.util.Scanner;
/**
* PK台
* 初始化角色数量
* 主页面
* 0.退出
* 1.查看所有角色
* 2.搜索角色
* 3.添加角色
* 4.删除角色
* 5.修改角色
* <p>
* 修改页面
* 修改哪个字段:
* 0.退出
* 1.名字
* 2.武器
* 3.技能
* 4.生命
*/
public class Main {
//操作类
CharacterManager characterManager = new CharacterManager();
Scanner sc = new Scanner(System.in);
Random rd = new Random();
public static void main(String[] args) throws InterruptedException {
Main main = new Main();
//初始化人数
main.initCharacterNumber();
//主页面
main.mainPage();
}
public void initCharacterNumber() {
Scanner sc = new Scanner(System.in);
System.out.print("初始化角色数量:");
characterManager.setCharacterArr(sc.nextInt());
}
//主页面
public void mainPage() throws InterruptedException {
System.out.println("======================================================\n" +
" 0.退出\n" +
" 1.查看所有角色\n" +
" 2.搜索角色\n" +
" 3.添加角色\n" +
" 4.删除角色\n" +
" 5.修改角色\n" +
" 6.开始PK");
System.out.print("选择:");
switch (sc.nextInt()) {
case 0:
System.exit(0);
case 1:
characterManager.ViewAllCharacter();
break;
case 2:
SearchCharacter();
break;
case 3:
AddCharacter();
break;
case 4:
DeleteCharacter();
break;
case 5:
UpdateCharacter();
break;
case 6:
TwoCharacterPk();
break;
default:
System.out.println("有误!");
}
mainPage();
}
//PK
public void TwoCharacterPk() throws InterruptedException {
Character firstCharacterNull = InputCharacterId("输入第一位角色编号:");
int firstCharacterId = characterManager.FindByCharacterId(firstCharacterNull);
if (firstCharacterId == -1) System.out.println("无人!");
else {
Character secondCharacterNull = InputCharacterId("输入第二位角色编号:");
int secondCharacterId = characterManager.FindByCharacterId(secondCharacterNull);
if (secondCharacterId == -1) System.out.println("无人!");
else {
//通过只包含Id的角色找到真正的对象
Character firstCharacter = characterManager.FindByCharacter(firstCharacterNull);
Character secondCharacter = characterManager.FindByCharacter(secondCharacterNull);
//HP
int firstCharacterHP = firstCharacter.getCharacterHP();
int secondCharacterHP = secondCharacter.getCharacterHP();
//名字
String firstCharacterName = firstCharacter.getCharacterName();
String secondCharacterName = secondCharacter.getCharacterName();
//武器名字
String firstCharacterArmsName = firstCharacter.getCharacterArms().getArmsName();
String secondCharacterArmsName = secondCharacter.getCharacterArms().getArmsName();
//武器攻击力
int firstCharacterArmsATK = firstCharacter.getCharacterArms().getArmsATK();
int secondCharacterArmsATK = secondCharacter.getCharacterArms().getArmsATK();
//技能名字
String firstCharacterSkillName = firstCharacter.getCharacterSkill().getSkillName();
String secondCharacterSkillName = secondCharacter.getCharacterSkill().getSkillName();
//技能攻击力
int firstCharacterSkillATK = firstCharacter.getCharacterSkill().getSkillATK();
int secondCharacterSkillATK = secondCharacter.getCharacterSkill().getSkillATK();
do {
//随机数 4~12 3倍数角色1技能 4倍数角色2技能 12都技能 其他普通攻击
int whoAttack = rd.nextInt(9) + 4;
if (whoAttack % 3 == 0 && whoAttack != 12) {
//双方造成的伤害,普通攻击+50%波动,技能+30%波动
int secondToFirstATK = secondCharacterArmsATK + rd.nextInt(secondCharacterArmsATK / 10 * 5);
int firstToSecondATK = firstCharacterSkillATK + rd.nextInt(firstCharacterSkillATK / 10 * 3);
firstCharacterHP -= secondToFirstATK;
secondCharacterHP -= firstToSecondATK;
System.out.println(firstCharacterName + "使用技能:" + firstCharacterSkillName + "对" + secondCharacterName + "造成了" + firstToSecondATK + "点伤害!");
System.out.println(secondCharacterName + "使用武器:" + secondCharacterArmsName + "对" + firstCharacterName + "造成了" + secondToFirstATK + "点伤害!");
} else if (whoAttack % 4 == 0 && whoAttack != 12) {
int secondToFirstATK = secondCharacterSkillATK + rd.nextInt(secondCharacterSkillATK / 10 * 3);
int firstToSecondATK = firstCharacterArmsATK + rd.nextInt(firstCharacterArmsATK / 10 * 5);
firstCharacterHP -= secondToFirstATK;
secondCharacterHP -= firstToSecondATK;
System.out.println(firstCharacterName + "使用武器:" + firstCharacterArmsName + "对" + secondCharacterName + "造成了" + firstToSecondATK + "点伤害!");
System.out.println(secondCharacterName + "使用技能:" + secondCharacterSkillName + "对" + firstCharacterName + "造成了" + secondToFirstATK + "点伤害!");
} else if (whoAttack == 12) {
int secondToFirstATK = secondCharacterSkillATK + rd.nextInt(secondCharacterSkillATK / 10 * 3);
int firstToSecondATK = firstCharacterSkillATK + rd.nextInt(firstCharacterSkillATK / 10 * 3);
firstCharacterHP -= secondToFirstATK;
secondCharacterHP -= firstToSecondATK;
System.out.println(firstCharacterName + "使用技能:" + firstCharacterSkillName + "对" + secondCharacterName + "造成了" + firstToSecondATK + "点伤害!");
System.out.println(secondCharacterName + "使用技能:" + secondCharacterSkillName + "对" + firstCharacterName + "造成了" + secondToFirstATK + "点伤害!");
} else {
int secondToFirstATK = secondCharacterArmsATK + rd.nextInt(secondCharacterArmsATK / 10 * 5);
int firstToSecondATK = firstCharacterArmsATK + rd.nextInt(firstCharacterArmsATK / 10 * 5);
firstCharacterHP -= secondToFirstATK;
secondCharacterHP -= firstToSecondATK;
System.out.println(firstCharacterName + "使用武器:" + firstCharacterArmsName + "对" + secondCharacterName + "造成了" + firstToSecondATK + "点伤害!");
System.out.println(secondCharacterName + "使用武器:" + secondCharacterArmsName + "对" + firstCharacterName + "造成了" + secondToFirstATK + "点伤害!");
}
System.out.print(firstCharacterHP + " ");
System.out.println(secondCharacterHP);
Thread.sleep(550);
} while (firstCharacterHP > 0 && secondCharacterHP > 0);
if (firstCharacterHP <= 0) System.out.println(secondCharacterName + "赢了!");
else System.out.println(firstCharacterName + "赢了!");
mainPage();
}
}
}
//InputLong 代码复用
public Long InputLong(String info) {
System.out.println(info);
return sc.nextLong();
}
//UpdateCharacter
public void UpdateCharacter() {
//调用管理类找人
Character updateCharacter = InputCharacterId("输入角色编号:");
int updateCharacterId = characterManager.FindByCharacterId(updateCharacter);
if (updateCharacterId == -1) System.out.println("无人!");
else {
System.out.println("修改哪个字段:\n" +
" 0.退出\n" +
" 1.名字\n" +
" 2.武器\n" +
" 3.技能\n" +
" 4.生命");
System.out.print("选择:");
//-1:修改失败
int a = -1;
switch (sc.nextInt()) {
case 0:
return;
case 1:
//调用管理类修改字段1
a = characterManager.UpdateCharacter(updateCharacter, 1, InputUpdate1And4FiledValue());
break;
case 2:
//调用管理类修改字段2
String[] armsFiledValue = InputUpdate2And3FiledValue();
a = characterManager.UpdateCharacter(updateCharacter, 2, new Arms(armsFiledValue[0], Integer.parseInt(armsFiledValue[1])));
break;
case 3:
//调用管理类修改字段3
String[] skillFiledValue = InputUpdate2And3FiledValue();
a = characterManager.UpdateCharacter(updateCharacter, 3, new Skill(skillFiledValue[0], Integer.parseInt(skillFiledValue[1])));
break;
case 4:
//调用管理类修改字段4
a = characterManager.UpdateCharacter(updateCharacter, 4, InputUpdate1And4FiledValue());
break;
default:
System.out.println("有误!");
}
if (a != -1) System.out.println("修改成功!");
//UpdateCharacter();
}
}
//InputUpdate1And4FiledValue 代码复用
public Object InputUpdate1And4FiledValue() {
System.out.print("输入值:");
return sc.next();
}
//InputUpdate2And3FiledValue 代码复用
public String[] InputUpdate2And3FiledValue() {
System.out.print("输入名字:");
String name = sc.next();
System.out.print(" 输入攻击力:");
String ATK = sc.next();
return new String[]{name, ATK};
}
//DeleteCharacter
public void DeleteCharacter() {
Character deleteCharacter = InputCharacterId("输入角色编号:");
int deleteId = characterManager.DeleteCharacter(deleteCharacter);
if (deleteId == -1) System.out.println("无人!");
else {
System.out.println("删除成功!");
}
}
//InputCharacterId 因为要用编号去查找 这方法返回只带编号的角色
public Character InputCharacterId(String info) {
System.out.print(info);
return new Character(sc.nextLong(), null, null, null, 0);
}
//AddCharacter
public Character AddCharacter() {
//随机4位数
long id = rd.nextInt(9000) + 1000;
System.out.print("输入名字:");
String name = sc.next();
System.out.print("输入武器名字:");
String armsName = sc.next();
System.out.print(" 输入武器攻击力:");
int armsATK = sc.nextInt();
Arms arms = new Arms(armsName, armsATK);
System.out.print("输入技能名字:");
String skillName = sc.next();
System.out.print(" 输入技能攻击力:");
int skillATK = sc.nextInt();
Skill skill = new Skill(skillName, skillATK);
System.out.print("输入生命:");
int hp = sc.nextInt();
Character character = new Character(id, name, arms, skill, hp);
int add = characterManager.AddCharacter(character);
if (add == -1) {
System.out.println("编号重复!");
} else if (add == -2) {
System.out.println("满员!");
} else {
System.out.println("添加成功");
}
return character;
}
//SearchCharacter
public void SearchCharacter() {
Character searchCharacter = InputCharacterId("输入角色编号:");
//先找到角色编号对应的数组下标
int searchCharacterId = characterManager.FindByCharacterId(searchCharacter);
if (searchCharacterId == -1) System.out.println("无人!");
else {
//通过下标获取角色对象
//Character searchCharacterCharacter = characterManager.FindByCharacter(characterManager.getCharacterArr()[searchCharacterId]);
Character searchCharacterCharacter = characterManager.getCharacterArr()[searchCharacterId];
characterManager.ViewSingleCharacter(searchCharacterCharacter, true);
}
}
}
1.查看所有角色
2.搜索角色
3.添加角色
4.删除角色
5.修改角色
6.开始PK
错题解析
1. 有如下程序段,则表达式a == b与s2 == s1的结果分别是:( A )。
int a ,b;
a= b = 5;
String s1 = “祝你今天考出好成绩!”;
String s2 = s1;
String s3=“祝你今天考出好成绩!”;
[A] true与true [B] false与true
[C] true与false [D] false与false
- 不该错的,只是直接给出字符常量的话,Java会自动在常量池中找到已经创建的字符串
2.下列说法中,正确的是:( A )
[A] 类是变量和方法的集合体 [B] 数组是无序数据的集合
[C ] 抽象类可以实例化 [D ] 类成员数据必须是公有的
- 就觉得A太过于绝对,去选了B,数组就是因为有索引的原因,他是有序的
3.给出下面代码, 那个语句是正确的?( A )
public class Person{
int arr[] = new int[10];
public static void main(String a[]) {
System.out.println(arr[1]);
}
}
[A] 编译时将产生错误; [B] 编译时正确,运行时将产生错误;
[C] 输出零; [D] 输出空;
- 考虑到了字符串有默认值,但没考虑到使用的是成员数组,要么给定static修饰,要么创建实例使用
4.下列说法正确的是( A )
[A] 能被java.exe成功运行的java class文件必须有main()方法
[B] Java源码编译完生成平台直接可运行的二进制文件
[C] Java源码直接运行在JVM中,JVM会对源码进行编译和运行
[D] class文件是字节码,字节码是和机器相关的可运行代码
- 选D去了,机器码才是机器可直接运行的代码
5.分析下面的Java 代码,当x=2 时,运行结果是( C )
switch ( x) {
case1: System.out.println(1) ;
case2:
case3: System.out.println(3) ;
case4: System.out.println(4) ;
}
(A) 没有输出任何结果
(B) 输出结果为3
© 输出结果是3 和4
(D) 输出结果是l 、3 和4
- 纯粹的大意了,看见没有break直接选了D,其实是在case2:后执行
面向对象总结
类:一组相关的属性和行为的集合,是一个抽象的概念。
对象:该类事物的具体表现形式,具体存在的个体。
成员变量:事物的属性
成员方法:事物的行为
比如小杨和老陈都有姓名、年龄、身高、体重等一些属性,并且两人都能够进行聊天、运动等相似的行为。
由于这两个人具有这些共性的地方,所以把它抽象出来,定义为一个类——人类,而小杨和老陈正是这个类中的个体(对象)。
类是对象的抽象,而对象是类的具体实例。
成员变量和局部变量的区别
位置:成员在方法外,局部在方法内
内存中:成员在堆中,局部在栈中
生命周期:成员随对象销毁,局部随方法销毁
初始值:成员有默认,局部必须赋值
面向过程和面向对象
举个例子,把大象放进冰箱这个问题
面向过程:1.第一步,先打开冰箱门。2.第二步.把大象放进冰箱。3.最后,关上冰箱门
面向对象:1.有人这个对象,他有把大象放进冰箱的方法。2.有大象这个对象,他有自身的属性。3.有冰箱这个对象,他有开门关门的方法,把东西冷藏的方法。
面向过程——步骤化
面向对象——行为化
封装
封装是指隐藏对象的属性和实现细节,仅对外提供公共访问方式。
简单来说就是用public、private、protected 等权限修饰符给属性方法上锁。不需要知道类中的这个方法的逻辑原理,只需要给他一个对外的接口能够调用这个方法即可,就比如冰箱,我们只需要往里面拿东西,放东西,不需要知道里面的结构。
定义好属性后,IDE可以自动生成get、set、toString、equals、构造方法。
继承
继承就是在一个已有类的基础上派生出新类—子类继承父类(只支持单继承但支持多层继承),子类就有了父类的属性和方法,提高了代码的复用性。
多态
指用一个方法,却有着不同的表现形式,比如在吃饭的方法上,不同的动物有不同的方式。
具体点就是写好一个总的方法类后,子类继承这个类,去覆盖重写这个方法,用父类对象去装子类对象,再去使用定义的方法,就是子类的方法了。
抽象类
每个动物都要吃饭,但是只说动物吃什么?不同的动物就有不同的吃法,所以动物吃饭是个抽象的概念,就有了抽象的方法,有了抽象的方法,这个类也要变成抽象的类,由子类去继承这个抽象类,比如猫狗继承后,必须覆盖重写吃的方法,狗吃骨头,猫吃鱼。
接口
接口与继承的用法类似也是子类继承父类,但与普通类不同,接口的继承叫实现,接口可以同时实现多个。
继承是一个 "是不是"的关系,而接口实现则是 "有没有"的关系。如果一个类继承了某个抽象类,则子类必定是抽象类的种类,而接口实现则是有没有、具备不具备的关系。
这周的面向对象更多是概念上的学习,在代码程序bug上没遇到什么问题,更多的是再写的时候要思考好整个程序的框架,要不要写继承,要不要给这个类写多态,也了解到在内存中对象、局部变量、常量分别放在哪块,继承多态可能只有多写程序,多思考才能真正掌握。以上