华清远见重庆中心——JAVA面向对象阶段知识点梳理
面向过程和面向对象编程
面向过程POP:所有的步骤依次进行,注意执行的细节。之前学习的java基础就是面向过程编程。
面向对象OOP:创建一些解决问题的的对象,各个对象调用各个的方法来共同完成一件事情。面向对象编程跟现实生活很类似,要干什么事情,把中途的各种事情交给各种领域的人或事物完成,再各自配合完成事情。
在面向对象中,给类定义的方法,具体实现过程也是面向过程编程的。
对象和类
类
具有相同属性和行为的对象的集合,称为一类
属性:描述对象的特征。在程序中,通过定义变量的形式表现属性。
行为:描述对象的动作。在程序中,通过定义方法的形式表现行为。
在程序中,通过定义一个class定义类,在类中定义变量描述属性,定义方法描述行为
定义类
语法
修饰符 class 类名{
属性
行为
}
对象
对象是类的一个实例,是类的具体表现
创建对象
类名 对象名=new 构造方法(参数);
创建的对象可以通过"."来调用类中非私有的属性和方法。
语法
对象名.属性;
对象名.方法名(参数);
成员变量、局部变量、静态常量
-
成员变量:定义在类中的属性,有默认值,通过对象访问;
-
局部变量:定义在方法中的属性,它没有默认值,只能在方法中赋值后才能使用。局部变量只能在其所在的方法中使用
-
静态常量:特殊的成员变量,用final static修饰。有默认值,可以通过类名直接访问。
class A{
String name;//成员变量,有默认值
final static String sex="女";//静态方法,可以通过类名直接访问
public void b(){
int age=0;//局部变量,使用前必须赋初值,且此变量只能在b方法内使用
}
}
构造方法
是一种特殊的方法,方法名和类名一致,没有返回值
访问修饰符 类名(){}
注意
-
构造方法没有返回值,且方法名必须和类名一致
-
使用new创建对象后,就调用对应的构造方法
-
每个类在定义后,都有一个隐藏的无参构造方法
-
如果自定义一个有参构造方法,无参构造方法失效,如果要使用,有参无参构造方法可以共存
-
构造方法通常用于限制创建对象时携带的参数,初始化成员变量
-
构造方法都是重载,不能重写
-
构造方法在执行时,不一定会创建对象,如抽象类也有构造方法,但无法创建抽象类对象,只能创建子类抽象类的子类对象时,自动调用抽象类的构造方法
面向对象三大特性
封装
封装就是将类中的属性使用private修饰,这样就能反正非当前类对其访问。保护作用
步骤
1.给类中的属性加上private修饰符
2.给类中的属性添加getXXX()方法读取属性值
3.给类中的属性添加setXXX()方法给属性赋值
继承
类A可以通过extends关键字继承类B
语法:类A extends 类B()
类A称为子类、派生类、subClass、基类
类B称为父类、超类、superClass、根类
继承后,子类可以访问父类中非私有(没有被private修饰的内容)的属性和方法
不同的子类如果有相同的代码,都可以把它们提取出来保存到父类中,从而减少子类中的代码冗余
继承的特点
-
如果多个类中有相同或者相似的代码吗,可以将这些代码提取出来定义到一个公共的类中,这个类就是父类,再让这些类继承这个父类,这些类就是子类,这样就能减少子类中的重复代码
-
子类对象可以直接访问父类中非私有(不用private)修饰的属性和方法
-
子类可以对父类的方法进行扩展或者覆盖,这称为方法重写,重写后,执行的是重写后的内容
-
Java中是单继承。一个子类只能有一个父类,一个父类可以有很多个子类
-
Java中可以多重继承。类A可以继承类B,类B可以继承类C,这时类A既是类B的子类,也是类C的子类,可以访问类B和类C中非私有的成员。
-
任何类都是Object的子类
-
在创建子类对象时候,会先执行父类中的相应的构造方法
重写Override
当子类继承父类后,可以对父类中非私有的方法进行扩展或覆盖,这个过程称为方法的重写
方法的重写要求
-
方法名,参数列表,返回值必须和父类一样
-
访问权限不能比父类更严格(访问修饰符的范围要么一致要么更大)
-
不能抛出比父类更大的异常
重载Overload
在一个类中,如果多个方法名相同,参数列表不同时,这些方法称为重载的方法
方法重载要求
-
方法名相同
-
参数列表不同(类型和数量不同)
-
与返回值无关
在一个类类中,只要同名不同参就是重载,而重写发生在继承中,在两个类中。
相关题目
- 说出重写和重载的异同
相同点:方法名不变
不同点:重载在一个类中,如构造方法就是典型的重载。重写在继承中,发生在两个类中。
- 构造方法能重载吗?能重写吗?
构造方法能重载,不能重写
- 构造方法在执行时,一定创建对象吗?
不一定,创建子类时会执行父类的构造方法,但不会创建父类的对象
关键字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(){
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(stringint)
super(name,age);
}
}
如果父类中有无参数的构造方法,在子类的构造方法中,可以不写super(),系统自动调用
如果父类中有带参数的构造方法,没有无参数的构造方法,在子类的构造方法中,必须先调用super(参数)先执行父类的构造方法
-
子类和父类都不写有参数的构造方法,都用默认的无参构造方法
-
父类中没有无参数的构造方法,子类中就必须写出调用父类中对应的构造方法
Object类
是所有类的父类。任何类都是它的子类,但没有用extends体现,每个类都可以访问Object类中的方法,或者对其进行重写
向上转型
子类对象可以用父类变量保存,即多态
A a=new A();
Object o=a;
向下转型
父类的对象也可以用子类变量保存,但是必须对父类对象进行强转型,类似于java基础时的基本数据类型double可以用int保存,但是必须强转型
Object o=new Object();
A a=(A)o;
多态
在继承关系中,子类的对象可以保存到父类的变量中。
多态通常应用于定义方法时,形参为一个父类或者接口,实参是一个子类对象
无法通过父类变量调用子类独有的方法,如果调用重写了父类的方法时,执行重写的内容
如
父类/父接口 对象=new 子类();
public class Person{
public void eat(){
System.out.println("原始人类吃生食");
}
}
public class Modern extends Person{
@Override
public void eat(){
System.out.println("现代人吃熟食");
}
public void fun(){
System.out.println("现代人会上网娱乐");
}
}
public void Main(){
public static void main(String[] args){
Person p=new Person();
p.eat();//父类中的方法
Modern m=new Modern();
m.fun();
m.eat();//调用重写的子类中的方法
Person p1=new Modern();
p1.fun();//无法调用,会报错
p1.eat();//这里调用的是重写后的方法
}
}
访问修饰符
访问修饰符可以限制某个类、属性或方法的访问权限
访问修饰符 | 含义 | 可以修饰 |
---|---|---|
public | 公共的 | 类,属性,方法 |
protected | 受保护的 | 属性,方法 |
不写 | 默认的 | 类,属性,方法 |
private | 私有的 | 属性,方法 |
同一个类 | 同一个包中的不同类 | 不同包中的子类 | 不同包中的非子类 | |
---|---|---|---|---|
public | √ | √ | √ | √ |
protected | √ | √ | √ | × |
不写 | √ | √ | × | × |
private | √ | × | × | × |
final关键字
修饰属性
当final修饰属性时,该属性的值不可更改
这时的属性称为常量。常量命名时,所有字母都大写,多个单词之间用__隔开
final 数据类型 常量名;
修饰方法
当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{
}
抽象abstract
修饰方法
使用:访问修饰符 abstract 返回值类型 方法名(参数类型 形参名字)
如果一个方法的方法体无法买啥,是其子类进行重写,可以将该方法定义为抽象方法。该抽象方法所在的类,也必须用abstract修饰,让其成为一个抽象类
//
public abstract class Game{
//
public abstract void startGame(Player player)
}
修饰类
使用:访问修饰符 abstract class 类名{}
如果类中有一个抽象方法,这个类必须是一个抽象类
抽象类不能被实例化(创建对象)
抽象类中煤科院存在非抽象方法,如geter/setter方法
当抽象类的构造方法执行时候,不会创建对象
当一个类不希望创建它本身的对象火灾它其中有抽象方法时,就将该类定义为抽象类
特点
修饰类:被修饰的类称为抽象类
-
抽象类不能被实例化,无法创建对象
-
抽象类中有构造方法时,在创建其子类对象时,自动调用执行
-
抽象类中可以有抽象方法,也可也有非抽象方法
-
抽象类的子类要么继续成为抽象类,要么将抽象类中的所有抽象方法进行重写
修饰方法:被修饰的方法称为抽象方法
-
抽象方法没有方法体。
-
抽象方法只能出现在抽象类或接口中。
-
abstract不能修饰构造方法和静态方法(static修饰)
接口interface
在java中,数据类型分为基本类型和引用类型
引用类型包含:数组,类和接口
所以接口是一种数据类,类似于类,在定义接口的时候,用interface替换class
由于Java是单继承,如果类A既要继承类B的内容,也要继承类C的内容时,如果用extends,只能选择一个,但如果使用implements interface,interface2,就能同时"继承"多个接口
通常用extends表示类A继承类B,用implements表示类A实现接口A,接口B…
接口是一个完全抽象类。一个类可以同时"继承"(implements实现)多个接口
extends和implements
类A extends 类B
类A当做类B的子类,继承
类A implmens 接口A,接口B…
类A当做接口A、接口B的实现类(“子类”)
接口A extends 接口B
接口A通过extends继承接口B
类A extends 类B implements 接口A,接口B…
类A是类B的子类,是接口A、接口B的实现类,同时能范文这三个"父类"中的数据。
注意:
-
接口是一个完全抽象类,其中的方法都是public abstract修饰的抽象方法,没有方法,属性也是public fanil static修饰的静态常量
-
接口没有构造方法,无法创建对象
-
接口通过implements关键字实现,实现它的类称为该接口的实现类
-
一个类可以实现多个接口
-
一个类实现接口后,必须重写里面的全部抽象方法
public interface 接口名{
//接口中的方法默认用public abstract修饰,表示公开的抽象方法
void fun();
default void fun(){
//jdk1.8之后,接口中可以有被default修饰的方法,称为默认方法,有方法体
}
static void fun2(){
//jdk1.8之后,接口中可以有被static修饰的方法,称为静态方法,有方法体
}
}
静态stactic
static是一个修饰符,可以修饰属性、方法、代码块
被static修饰的内容,称为静态成员。静态成员在类加载的时候,就会保存到内容中,可以脱离对象存在。
所有访问静态成员时,可以不用创建对象,直接通过类名访问,如Math中的属性和方法都是静态的,所以直接通过Math访问。
什么时候使用static
如果某个属性或方法被高度重用时,可以将其定义为static静态的。
这样这些属性就会脱离对象,在类加载时就加载到内存中,从而直接通过类名即可访问。或不想创建对象就想使用该类中的属性或方法时,将它们定义为静态的。
如何访问静态成员
直接通过类名就能访问静态成员。也可以通过对象访问。
静态常量
static修饰属性时,通常和final一起使用,表示静态常量
public class Person{
public final static String COUNTRY="中华人民共和国"
}
public class test{
public static void main(String[] args){
//静态成员直接通过类名访问
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[] args){
//静态成员直接通过类名访问
;
}
}
静态代码块
public class Person{
static{
//这里的代码在类加载时自动执行
}
}
特点
- 静态方法中只能使用静态成员,不能使用非静态成员
- 非静态方法中可以使用静态方法
- 静态方法中不能使用this关键字
部分作业代码
游戏厅
package com.hqyj.test7;
/*
* 定义游戏父类
* */
public class Game {
private String gameName;
public String getGameName() {
return gameName;
}
public void setGameName(String gameName) {
this.gameName = gameName;
}
public Game(String gameName) {
this.gameName = gameName;
}
//游戏方法 游戏细节需要子类重写
public void starGame(Player player){
//根据游戏不同执行不同的流程
}
}
package com.hqyj.test7;
import java.util.Scanner;
/*
* 模拟玩家玩游戏
* 玩家有注册,登录等功能
* 用户名,余额属性
* 游戏
* 属性
* 游戏名等属性
* 启动游戏方法
* 游戏厅
* 玩游戏方法(游戏,玩家)
* 充值方法(玩家对象,金额)
* */
public class GameHouse {
//定义一个玩家数组,保存玩家数据
static Player[] p=new Player[10];
//玩家注册
public boolean logon(Player player){
for (int i=0;i<p.length;i++){
if (p[i]!=null && p[i].equals(player)){
return false;
}
}
for (int i=0;i<p.length;i++){
if (p[i]==null){
p[i]=player;
return true;
}
}
return false;
}
/*
* 玩家登陆
* */
public boolean register(String name,String pwd){
for (int i=0;i<p.length;i++){
if (p[i]!=null && p[i].getName().equals(name) && p[i].getPwd().equals(pwd)){
return true;
}
}
return false;
}
//取出数组中用户是登录的哪个号数组的下标
public int quchuxiabiao(String name,String pwd){
for (int i=0;i<p.length;i++){
if (p[i]!=null && p[i].getName().equals(name) && p[i].getPwd().equals(pwd)){
return i;
}
}
return 0;
}
/*
* 玩家玩游戏
* */
public void play(Player p,Game g){
System.out.println(p.getName()+"正在玩"+g.getGameName());
g.starGame(p);
}
/*
* 玩家充值
* */
public void charge(Player p,double price){
if (price>0){
p.setPrice(p.getPrice()+price);
}else {
System.out.println("你没钱啦");
}
}
public static void main(String[] args) {
Scanner sc=new Scanner(System.in);
System.out.println("欢迎来到游戏大厅");
GameHouse gh = new GameHouse();
while (true) {
System.out.println("1.注册\t2.登录\t3.退出");
switch (sc.nextInt()){
case 1:
System.out.println("请输入账号:");
String name=sc.next();
System.out.println("请输入密码:");
String pwd=sc.next();
Player player=new Player(name,pwd);
gh.logon(player);
System.out.println("注册成功");
for (Player player1 : p) {
if (player1!=null){
System.out.println(player1.getName()+"\t"+player1.getPwd());
}
}
break;
case 2:
System.out.println("请输入账号");
String name1=sc.next();
System.out.println("请输入密码:");
String pwd1=sc.next();
if (gh.register(name1,pwd1)){
int a=gh.quchuxiabiao(name1,pwd1);
System.out.println("请充值,输入充值金额");
double money=sc.nextDouble();
gh.charge(p[a],money);
while (true) {
System.out.println("1.猜数游戏");
System.out.println("2.猜拳游戏");
System.out.println("3.模拟双色球游戏");
System.out.println("4.退出");
if (p[a].getPrice()>0){
switch (sc.nextInt()){
case 1:
gh.play(p[a],new GuessNum("猜数游戏"));
System.out.println("余额"+p[a].getPrice());
break;
case 2:
gh.play(p[a],new GuessingGame("猜拳游戏"));
System.out.println("余额"+p[a].getPrice());
break;
case 3:
gh.play(p[a],new SSQGame("模拟双色球游戏"));
System.out.println("余额"+p[a].getPrice());
break;
case 4:
System.exit(0);
}
}
}
}else{
System.out.println("账户或密码错误");
}
break;
case 3:
System.exit(0);
}
}
}
}
package com.hqyj.test7;
import java.util.Random;
import java.util.Scanner;
/*
* 猜拳游戏
* 1-石头
* 2-剪刀
* 3-布
*
* 3局2胜
* */
public class GuessingGame extends Game{
public GuessingGame(String gameName) {
super(gameName);
}
@Override
public void starGame(Player player) {
System.out.println("欢迎来到猜拳游戏");
Scanner sc = new Scanner(System.in);
Random rd=new Random();
//定义电脑赢的局数
int comWin=0;
//定义玩家赢的局数
int humanWin=0;
while (true) {
if (player.getPrice()>0){
player.setPrice(player.getPrice()-2);
//判断是否赢2局,任意一方赢2局,游戏结束
if (comWin==2){
System.out.println("电脑胜利");
return;
}
if (humanWin==2){
System.out.println("玩家胜利,奖励10元");
player.setPrice(player.getPrice()+10);
return;
}
System.out.println("请输入1.石头\t2.剪刀\t3.布");
//判断输入的数字是否在1-3范围内,如果不在,跳过此次循环
int human = sc.nextInt();
if (human<1 || human>3){
System.out.println("输入有误,请重新输入");
continue;
}
int com = rd.nextInt(3)+1;
switch (com){
case 1:
System.out.println("电脑出拳为石头");
if (human==1){
System.out.println("你出拳结果为石头,平局");
}else if (human==2){
System.out.println("你出拳结果为剪刀,你输了");
comWin++;
}else {
System.out.println("你出拳结果为布,你赢了");
humanWin++;
}
break;
case 2:
System.out.println("电脑出拳为剪刀");
if (human==1){
System.out.println("你出拳为结果石头,你赢了");
humanWin++;
}else if (human==2){
System.out.println("你出拳为结果剪刀,平局");
}else {
System.out.println("你出拳为结果布,你输了");
comWin++;
}
break;
case 3:
System.out.println("电脑出拳为布");
if (human==1){
System.out.println("你出拳为结果石头,你输了");
comWin++;
}else if (human==2){
System.out.println("你出拳为结果剪刀,你赢了");
humanWin++;
}else {
System.out.println("你出拳为结果布,平局");
}
break;
}
}
}
}
}
package com.hqyj.test7;
import java.util.Random;
import java.util.Scanner;
public class GuessNum extends Game{
public GuessNum(String gameName) {
super(gameName);
}
@Override//重写玩游戏方法
public void starGame(Player player) {
Scanner sc = new Scanner(System.in);
Random rd = new Random();
System.out.println("欢迎进入猜数游戏");
int res = 0;
int count=0;
while (true){
System.out.println("请选择难度\t1.简单:猜测1-100以内的数\t2.中等:猜测1-1000以内的数\t3.困难:猜测1-10000以内的数\t4.退出");
int i = sc.nextInt();
switch (i){
case 1:
System.out.println("你选择了简单模式");
res= rd.nextInt(100);
break;
case 2:
System.out.println("你选择了中等模式");
res = rd.nextInt(1000);
break;
case 3:
System.out.println("你选择了困难模式");
res=rd.nextInt(10000);
break;
case 4:
return;
}
while (true) {
if (player.getPrice()>0){
player.setPrice(player.getPrice()-2);
System.out.println("请输入你猜测的数");
int guess=sc.nextInt();
if (guess>res){
System.out.println("你猜大啦");
}else if (guess<res){
System.out.println("你猜小啦");
}else {
System.out.println("恭喜你你猜对啦");
if (i==1){
player.setPrice(player.getPrice()+10);
System.out.println("奖励10元");
}else if (i==2){
player.setPrice(player.getPrice()+30);
System.out.println("奖励30元");
}else {
player.setPrice(player.getPrice()+50);
System.out.println("奖励50元");
}
break;
}
}else {
System.out.println("游戏币不足");
break;
}
}
}
}
}
package com.hqyj.test7;
import java.util.Objects;
/*
* 玩家类
* 用户名
* 余额
* */
public class Player {
private String name;
private double price;
private String pwd;
public Player(String name,String pwd) {
this.name = name;
this.pwd=pwd;
}
public Player() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Player player = (Player) o;
return Objects.equals(name, player.name) &&
Objects.equals(pwd, player.pwd);
}
public String getPwd() {
return pwd;
}
public void setPwd(String pwd) {
this.pwd = pwd;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public double getPrice() {
return price;
}
public void setPrice(double price) {
this.price = price;
}
}
package com.hqyj.test7;
import java.util.Arrays;
import java.util.Random;
import java.util.Scanner;
public class SSQGame extends Game {
public SSQGame(String gameName) {
super(gameName);
}
@Override
public void starGame(Player player) {
Random rd = new Random();
Scanner sc=new Scanner(System.in);
int[] red=new int[6];
if (player.getPrice()>0){
player.setPrice(player.getPrice()-2);
//随机6位红色球
for (int i = 0; i < red.length; i++) {
red[i]=rd.nextInt(33)+1;
for (int j=0;j<i;j++){
if (red[i]==red[j]){
i--;
}
}
}
Arrays.sort(red);
//定义篮球
int blue=rd.nextInt(16)+1;
//定义一个购买的红球数组
int[] buyred=new int[6];
//购买的红球号码
System.out.println("请输入你要购买的红球号码");
for (int i = 0; i < buyred.length; i++) {
System.out.println("请输入第"+(i+1)+"个球号码");
int buy=sc.nextInt();
if (buy<=33 && buy>0){
buyred[i]=buy;
for (int j=0;j<i;j++){
if (buyred[i]==buyred[j]){
System.out.println("不能购买相同的号码");
i--;
}
}
}else{
System.out.println("请输入1-33之间的号码");
continue;
}
}
//把购买的红色球数组排序
Arrays.sort(buyred);
//定义购买的蓝色号码
System.out.println("请输入你要购买的蓝色球号码");
int buyblue=0;
while (true) {
int bl= sc.nextInt();
if (bl>0 && bl<=16){
buyblue=bl;
break;
}else {
System.out.println("只能输入1-16的数");
}
}
//遍历购买的红色数组
System.out.println("你购买的红色球为:");
for (int br : buyred) {
System.out.print(br+"\t");
}
System.out.println("你购买的蓝色球为:");
System.out.println(buyblue);
System.out.println("中奖号码");
System.out.println("红球号码");
//遍历随机生成的红色球数组
for (int r : red) {
System.out.print(r+"\t");
}
System.out.println("篮球号码");
System.out.println(blue);
//判断中将,数组中的数据循环比较,如果两个数据相同,则count+1;
int count=0;
for (int m=0;m< red.length;m++){
for (int n=0;n<m;n++){
if (red[m]==buyred[n]){
count++;
}
}
}
if (buyred==red && blue==buyblue){
System.out.println("恭喜你,中一等奖");
player.setPrice(player.getPrice()+5000000);
}else if (red==buyred){
System.out.println("恭喜你,中二等奖");
player.setPrice(player.getPrice()+1000000);
}else if (count==5 && blue==buyblue){
System.out.println("恭喜你,中三等奖");
player.setPrice(player.getPrice()+3000);
}else if (count==5 || (count==4 && blue==buyblue)){
System.out.println("恭喜你,中四等奖");
player.setPrice(player.getPrice()+200);
}else if (count==4 ||(count==3 && buyblue==blue)){
System.out.println("恭喜你,中五等奖");
player.setPrice(player.getPrice()+10);
}else if ((count==2 && blue==buyblue) || (count==1 && blue==buyblue) || buyblue==blue){
System.out.println("恭喜你,中六等奖");
player.setPrice(player.getPrice()+5);
}else{
System.out.println("抱歉,你没有中奖");
}
}
return;
}
}
真人pk,在写此代码的时候遇到了困难,试了好久,数组第二个元素传不进去,找了好久,终于找到了,原来是add方法的return true写在了循环外,所以一直传不进去
解决这个问题后,又出现了一个问题,我的fight只循环两次,我打了几次断点后认定问题在fight方法上,但是也是找了好久没找到,最后还是在老师的帮助下找到了,原来把getHp打快了打成了getId,最后终于成功运行。也给了我一个小小的教训,写代码必须心细,而且不能慌。
package com.hqyj.HomeWork;
import java.util.Objects;
public class Character {
private int id;
private String name;
private String group;
private String arms;
private String skill;
private int hp=1000;
public Character(int id, String name, String group, String arms,String skill) {
this.id = id;
this.name = name;
this.group = group;
this.arms = arms;
this.skill=skill;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Character character = (Character) o;
return id == character.id &&
Objects.equals(name, character.name) &&
Objects.equals(group, character.group) &&
Objects.equals(arms, character.arms) &&
Objects.equals(skill, character.skill);
}
public String getSkill() {
return skill;
}
public void setSkill(String skill) {
this.skill = skill;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public int getHp() {
return hp;
}
public void setHp(int hp) {
this.hp = hp;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getGroup() {
return group;
}
public void setGroup(String group) {
this.group = group;
}
public String getArms() {
return arms;
}
public void setArms(String arms) {
this.arms = arms;
}
}
package com.hqyj.HomeWork;
import java.util.Random;
import java.util.Scanner;
public class Player {
//定义一个数组保存游戏角色
Character[] list=new Character[10];
//添加角色方法
public boolean add(Character character){
for (int i=0;i<list.length;i++){
if (list[i]!=null && list[i].equals(character)){
return false;
}
}
for (int i = 0; i < list.length; i++) {
if (list[i]==null){
list[i]=character;
return true;
}
}
return false;
}
//查看所有角色列表
public void showAll(){
System.out.println("游戏角色列表");
System.out.println("姓名\t\t阵营\t\t武器\t\t技能\t\t血量");
for (Character c : list) {
if (c!=null){
System.out.print(c.getName()+"\t"+c.getGroup()+"\t"+c.getArms()+"\t"+c.getSkill()+"\t"+c.getHp());
System.out.println();
}
}
}
//根据编号得到角色
public Character findOne(int id){
for (int i=0;i<list.length;i++){
if(list[i]!=null && list[i].getId()==id){
return list[i];
}
}
return null;
}
//战斗方法
public void fight(Character c,Character c2) throws InterruptedException {
Random rd = new Random();
System.out.println("测试");
if(c!=null && c2!=null){
while (true) {
if (c2.getHp()<=0){
System.out.println(c.getName()+"战胜了"+c2.getName());
break;
}
if (c.getHp()<=0){
System.out.println(c2.getName()+"战胜了"+c.getName());
break;
}
Thread.sleep(500);
int rdnum=rd.nextInt(9)+4;
int a=rd.nextInt(28)+123;
if (rdnum%3==0){
System.out.println("阵营为"+c.getGroup()+"的"+c.getName()+"使用"+c.getArms()+"发动技能"+c.getSkill()+"攻击了来自"+c2.getGroup()+"阵营为的"+c2.getName()+"造成了"+a+"点伤害");
c2.setHp(c2.getHp()-a);
}
if (rdnum%4==0){
System.out.println("阵营为"+c2.getGroup()+"的"+c2.getName()+"使用"+c2.getArms()+"发动技能"+c2.getSkill()+"攻击了来自"+c.getGroup()+"阵营为的"+c.getName()+"造成了"+a+"点伤害");
c.setHp(c2.getHp()-a);
}
if (rdnum==5 || rdnum==7){
System.out.println("阵营为"+c.getGroup()+"的"+c.getName()+"使用"+c.getArms()+"攻击了来自"+c2.getGroup()+"阵营为的"+c2.getName()+"造成了10点伤害");
System.out.println("阵营为"+c2.getGroup()+"的"+c2.getName()+"使用"+c2.getArms()+"攻击了来自"+c.getGroup()+"阵营为的"+c.getName()+"造成了10点伤害");
c.setHp(c.getHp()-10);
c2.setHp(c2.getHp()-10);
}
}
}else{
System.out.println("某个角色为空");
}
}
public void menu() throws InterruptedException {
Scanner sc=new Scanner(System.in);
System.out.println("欢迎来到真人快打");
while (true) {
System.out.println("1.添加角色");
System.out.println("2.查看所有角色");
System.out.println("3.开打!");
System.out.println("4.退出");
int i=sc.nextInt();
switch (i){
case 1:
System.out.println("输入角色id");
int id=sc.nextInt();
System.out.println("输入角色名称");
String name=sc.next();
System.out.println("输入角色阵营");
String group=sc.next();
System.out.println("输入角色武器");
String arms=sc.next();
System.out.println("输入角色技能");
String skill=sc.next();
Character c=new Character(id,name,group,arms,skill);
add(c);
break;
case 2:
showAll();
break;
case 3:
System.out.println("请选择出战的第一个角色");
int fight=sc.nextInt();
System.out.println("请选择出战的第二个角色");
int fight2=sc.nextInt();
fight(findOne(fight),findOne(fight2));
case 4:
System.exit(0);
break;
}
}
}
//主方法
public static void main(String[] args) throws InterruptedException {
Player player=new Player();
player.menu();
}
}
总结和心得
这一周学习完成了java面向对象阶段,其实在学习过程中还是有一些担忧的,也遇到了一些困难,比如代码不熟练或者是不够细心,在学习重写equals方法时,第一时间并不是很能理解,需要自己在课后继续钻研,学习代码的过程确实也是痛并快乐着,痛苦的是在学习的途中会遇到很多问题,而且学习的时间也是充满枯燥,也是对自己的一个挑战,但是当写出来代码的那一瞬间的成就感油然而生,感觉像是创造了一个生命。这种喜悦,不知如何描述。所以继续加油吧。