1. 编程实现以下需求:
定义一个长度为[16][16]的整型二维数组并输入或指定所有位置的元素值,分别实现二维数组中所有行和所有列中所有元素的累加和并打印。
再分别实现二维数组中左上角到右下角和右上角到左下角所有元素的累加和并打印。
package com.lagou.array;
import java.util.Scanner;
/**
* 编程实现数组中指定元素累加的功能
*/
public class ArraySumTest {
public static void main(String[] args){
// 1.声明一个16行16列的二维数组,数组元素的默认值为0
int[][] arr = new int[16][16];
// 2.提示用户输入二维数组中所有位置的元素值
// 由于从键盘输入纯粹是体力活,因此下面使用固定的数据作为数组的元素值
//Scanner sc = new Scanner(System.in);
for (int i = 0; i <= 15; i++) {
for (int j = 0; j <= 15; j++) {
//System.out.println("请输入下标为[" + i + "][" + j + "]位置的元素值:");
//arr[i][j] = sc.nextInt();
arr[i][j] = 1;
}
}
// 3.打印二维数组中的所有元素值
for (int i = 0; i <= 15; i++) {
for(int j = 0; j <= 15; j++) {
System.out.print(arr[i][j] + " ");
}
System.out.println();
}
System.out.println("---------------------------------------------------");
// 4.实现每一行中所有元素值的和并打印
// 记录每一行所有元素累加和的规则是:行下标保持不变,列下标从0到15
for (int i = 0; i <= 15; i++) {
// 声明变量用于记录当前行所有元素的和
int sum = 0;
for(int j = 0; j <= 15; j++) {
sum += arr[i][j];
}
System.out.println("第" + (i+1) + "行的所有元素的累加和为:" + sum);
}
System.out.println("---------------------------------------------------");
// 5.实现每一列中所有元素值的和并打印
// 记录每一列中所有元素累加和的规则是:列下标保持不变,行下标从0到15
for (int j = 0; j <= 15; j++) {
// 声明变量用于记录当前列所有元素的和
int sum = 0;
for(int i = 0; i <= 15; i++) {
sum += arr[i][j];
}
System.out.println("第" + (j+1) + "列的所有元素的累加和为:" + sum);
}
System.out.println("---------------------------------------------------");
// 6.实现从左上角到右下角所有元素的和并打印
// 记录左上角到右下角所有元素累加和的规则是:行列下标同时从0到15,同时加1
// 声明变量用于记录当前列所有元素的和
int sum = 0;
for(int i = 0; i <= 15; i++) {
sum += arr[i][i];
}
System.out.println("从左上角到右下角所有元素的累和为:" + sum);
System.out.println("---------------------------------------------------");
// 7.实现从右上角到左下角的元素和并打印
// 记录右上角到左下角所有元素累加和的规则是:行加1,列减1,由于行列都是15,因此相加结果为15
sum = 0;
for(int i = 0; i <= 15; i++) {
sum += arr[i][15-i];
}
System.out.println("从左上角到右下角所有元素的累和为:" + sum);
}
}
2. 编程实现控制台版并支持两人对战的五子棋游戏。
(1)绘制棋盘 - 写一个成员方法实现
(2)提示黑方和白方分别下棋并重新绘制棋盘 - 写一个成员方法实现。
(3)每当一方下棋后判断是否获胜 - 写一个成员方法实现。
(4)提示: 采用二维数组来模拟并描述棋盘,棋盘如下:
package com.lagou.gobang;
import java.util.Scanner;
/**
* 编程实现控制台版的五子棋游戏,支持两人对战
*/
public class Gobang {
// 自定义二维数组来描述棋盘,默认初始值为0
int[][] chessBoard = new int[16][16];
// 自定义成员方法来绘制棋盘
void paint() {
// 1.先绘制棋盘中第一行的坐标信息,也就是列坐标信息
for (int i = 0; i < 17; i++) {
if (0 == i) {
System.out.print(" ");
} else {
// 按照十六进制的格式打印i-1的数值
System.out.printf("%x ", i-1);
}
}
System.out.println();
// 2.绘制棋盘中除了第一行之外的其他部分以及行坐标信息
for (int i = 0; i < 16; i++) {
// 用于打印行坐标信息
System.out.printf("%x ", i);
for (int j = 0; j < 16; j++) {
// 刚开始棋盘中的所有内容都是+,因此直接打印
if (0 == chessBoard[i][j]) {
System.out.print("+ ");
} else if (1 == chessBoard[i][j]) {
System.out.print("● ");
} else {
System.out.print("○ ");
}
}
// 打印完毕一行的所有内容之后进行换行
System.out.println();
}
}
// 自定义成员方法来提示黑方和白方分别下棋
void play() {
// 定义标志位来进行黑方和白方的切换,true代表黑方,false代表白方
boolean flag = true;
// 不断地分别提示黑方和白方下棋
while (true) {
System.out.println("请" + (flag ? "黑方" : "白方") + "输入落子坐标(x y):");
Scanner sc = new Scanner(System.in);
int ix = sc.nextInt();
int iy = sc.nextInt();
// 根据用户输入的坐标来调整棋盘中的图案,策略为改变数组的元素值,其中不合理的下标判断这里省略了
// 当黑方落子时就将数组中对应元素值改为1,当白方落子时就将数组中对应元素改为2
chessBoard[ix][iy] = (flag? 1: 2);
// 重新绘制图案
paint();
// 判断当前方是否胜利,若胜利就立刻结束游戏
if (judge(ix, iy)) {
System.out.println("恭喜" + (flag ? "黑方" : "白方") + "胜利了!");
break;
}
// 此时切换下棋方
flag = !flag;
}
}
// 自定义成员方法来判断用户是否获胜,获胜的规则是:任意相同颜色的5个棋子连成一线
boolean judge(int ix, int iy) {
// 1.判断竖向是否连成一线,则需要以该点为中心向上四个点向下四个点
// 声明变量来统计竖向相同颜色棋子的个数,先统计向上同色棋子的个数
// 先统计向上颜色相同的个数
int count = 1;
for (int i = ix - 1; i >= 0; i--) {
// 若当前点代表的棋子与上述某个点代表的棋子不一样,则向上统计结束
if (chessBoard[ix][iy] != chessBoard[i][iy]) {
break;
}
count++;
}
// 再统计向下颜色相同的个数
for (int i = ix + 1; i <= 15; i++) {
if (chessBoard[ix][iy] != chessBoard[i][iy]) {
break;
}
count++;
}
if (5 == count) {
return true;
}
// 2.判断横向是否连成一线,则需要以该点为中心向左四个点向右四个点
count = 1;
// 先统计向左颜色相同的个数
for (int j = iy - 1; j >= 0; j--) {
// 若当前点代表的棋子与上述某个点代表的棋子不一样,则向上统计结束
if (chessBoard[ix][iy] != chessBoard[ix][j]) {
break;
}
count++;
}
// 再统计向右颜色相同的个数
for (int j = iy + 1; j <= 15; j++) {
if (chessBoard[ix][iy] != chessBoard[ix][j]) {
break;
}
count++;
}
if (5 == count) {
return true;
}
// 3.判断左上到右下是否连成一线,则需要以该点为中心向左上四个点向右下四个点
count = 1;
// 先统计左上颜色相同的个数
for (int i = ix-1, j = iy - 1; i >= 0 && j >= 0; i--, j--) {
// 若当前点代表的棋子与上述某个点代表的棋子不一样,则向上统计结束
if (chessBoard[ix][iy] != chessBoard[i][j]) {
break;
}
count++;
}
// 再统计右下颜色相同的个数
for (int i = ix+1, j = iy + 1; i <= 15 && j <= 15; i++, j++) {
if (chessBoard[ix][iy] != chessBoard[i][j]) {
break;
}
count++;
}
if (5 == count) {
return true;
}
// 4.判断右上到左下是否连成一线,则需要以该点为中心向右上四个点向左下四个点
count = 1;
// 先统计右上颜色相同的个数
for (int i = ix-1, j = iy + 1; i >= 0 && j <= 15; i--, j++) {
// 若当前点代表的棋子与上述某个点代表的棋子不一样,则向上统计结束
if (chessBoard[ix][iy] != chessBoard[i][j]) {
break;
}
count++;
}
// 再统计左下颜色相同的个数
for (int i = ix+1, j = iy - 1; i <= 15 && j >= 0; i++, j--) {
if (chessBoard[ix][iy] != chessBoard[i][j]) {
break;
}
count++;
}
if (5 == count) {
return true;
}
// 当上述所有情况都不成立时,表示该下棋方没有获胜
return false;
}
}
3. 按照要求设计并实现以下实体类和接口。
3.1 第一步:设计和实现以下类
(1)手机卡类 特征:卡类型、卡号、用户名、密码、账户余额、通话时长(分钟)、上网流量 行为:显示(卡号 + 用户名 + 当前余额)
(2)通话套餐类 特征:通话时长、短信条数、每月资费 行为: 显示所有套餐信息 (3)上网套餐类 特征:上网流量、每月资费 行为:显示所有套餐信息
(4)用户消费信息类 特征:统计通话时长、统计上网流量、每月消费金额
3.2 第二步:设计和实现以下枚举类 手机卡的类型总共有 3 种:大卡、小卡、微型卡
3.3 第三步:实体类的优化 将通话套餐类和上网套餐类中相同的特征和行为提取出来组成抽象套餐类。
3.4 第四步:创建并实现以下接口
(1)通话服务接口 抽象方法: 参数1: 通话分钟, 参数2: 手机卡类对象 让通话套餐类实现通话服务接口。
(2)上网服务接口 抽象方法: 参数1: 上网流量, 参数2: 手机卡类对象 让上网套餐类实现上网服务接口。
3.5 第五步:进行代码测试
编写测试类使用多态格式分别调用上述方法,方法体中打印一句话进行功能模拟即可。
package com.lagou.library;
/**
* 编程实现手机卡类型的实现
*/
public enum CardTypeEnum {
BIG("大卡"), SMALL("小卡"), MICRO("微型卡");
private final String desc; // 用于描述卡类型的成员变量
private CardTypeEnum(String desc) { this.desc = desc; }
}
package com.lagou.library;
/**
* 编程实现手机卡类的封装
*/
public class PhoneCard {
// 1.私有化成员变量,使用private关键字修饰
private CardTypeEnum cardType; // 用于描述卡类型的成员变量
private String cardNumber; // 用于描述卡号的成员变量
private String userName; // 用于描述用户名的成员变量
private String password; // 用于描述密码的成员变量
private double balance; // 用于描述账户余额的成员变量
private int talkTime; // 用于描述通话时长的成员变量
private double netFlow; // 用于描述上网流量的成员变量
// 3.在构造方法中调用set方法进行合理值的判断
public PhoneCard() {
}
public PhoneCard(CardTypeEnum cardType, String cardNumber, String userName, String password, double balance, int talkTime, double netFlow) {
setCardType(cardType);
setCardNumber(cardNumber);
setUserName(userName);
setPassword(password);
setBalance(balance);
setTalkTime(talkTime);
setNetFlow(netFlow);
}
// 2.提供公有的get和set方法,并在方法中进行合理值的判断,以通话时长为例进行处理
public CardTypeEnum getCardType() {
return cardType;
}
public void setCardType(CardTypeEnum cardType) {
this.cardType = cardType;
}
public String getCardNumber() {
return cardNumber;
}
public void setCardNumber(String cardNumber) {
this.cardNumber = cardNumber;
}
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;
}
public double getBalance() {
return balance;
}
public void setBalance(double balance) {
this.balance = balance;
}
public int getTalkTime() {
return talkTime;
}
public void setTalkTime(int talkTime) {
if (talkTime >= 0) {
this.talkTime = talkTime;
} else {
System.out.println("通话时长不合理哦!!!");
}
}
public double getNetFlow() {
return netFlow;
}
public void setNetFlow(double netFlow) {
this.netFlow = netFlow;
}
// 4.提供显示(卡号 + 用户名 + 当前余额)的方法
public void show(){
System.out.println("卡号为: "+ getCardNumber() + ",用户名为: " + getUserName() + ",当前余额为: " + getBalance() + "元!");
}
}
package com.lagou.library;
/**
* 编程实现将通话套餐类和上网套餐类中相同的特征和行为提取出来组成抽象套餐类的封装
*/
public abstract class AbstractPackage {
// 1.私有化成员变量,使用private关键字修饰
private double rate; // 用于描述每月资费的成员变量
// 3.在构造方法中调用set方法实现合理值的判断
public AbstractPackage() {
}
public AbstractPackage(double rate) {
setRate(rate);
}
// 2.提供公有的get和set方法,并在方法体中进行合理值的判断
public double getRate() {
return rate;
}
public void setRate(double rate) {
if (rate >= 0) {
this.rate = rate;
} else {
System.out.println("每月资费不合理哦!!!");
}
}
// 4.提供显示所有套餐信息的抽象方法
public abstract void show();
}
package com.lagou.library;
/**
* 编程实现用户消费信息类的封装
*/
public class UserConsumption {
// 1.私有化成员变量,使用private关键字修饰
private int talkTime; // 用于描述通话时长的成员变量
private double netFlow; // 用于描述上网流量的成员变量
private double rate; // 用于描述每月资费的成员变量
// 3.在构造方法中调用set方法进行合理值的判断
public UserConsumption() {
}
public UserConsumption(int talkTime, double netFlow, double rate) {
setTalkTime(talkTime);
setNetFlow(netFlow);
setRate(rate);
}
// 2.提供公有的get和set方法,并在方法体中进行合理值的判断,判断这里省略了
public int getTalkTime() {
return talkTime;
}
public void setTalkTime(int talkTime) {
this.talkTime = talkTime;
}
public double getNetFlow() {
return netFlow;
}
public void setNetFlow(double netFlow) {
this.netFlow = netFlow;
}
public double getRate() {
return rate;
}
public void setRate(double rate) {
this.rate = rate;
}
// 4.实现用户消费信息的打印
public void show() {
System.out.println("用户消费信息: 通话时间为: " + getTalkTime() + ",上网流量为: " + getNetFlow() + ",月资费为: " + getRate());
}
}
package com.lagou.library;
/**
* 编程实现通话服务接口
*/
public interface TalkService {
// 自定义抽象方法描述通话服务的功能
public abstract void talk(int talkTime, PhoneCard phoneCard);
}
package com.lagou.library;
/**
* 编程实现上网服务接口
*/
public interface NetService {
// 自定义抽象方法描述上网服务的功能
public abstract void net(double netFlow, PhoneCard phoneCard);
}
package com.lagou.library;
/**
* 编程实现各种类库的测试
*/
public class MainTest {
public static void main(String[] args) {
// 1.声明PhoneCard类型的引用指向PhoneCard类型的对象作为下面方法的实参
PhoneCard phoneCard = new PhoneCard();
// 2.声明NetService类型的引用指向NetPackage类型的对象,也就是接口引用指向实现类对象从而形成了多态
NetService netService = new NetPackageServiceImpl();
netService.net(66, phoneCard);
System.out.println("---------------------------------------------------");
// 3.声明TalkService类型的引用指向TalkPackage类型的对象,也就是接口引用指向实现类对象从而形成了多态
TalkService talkService = new TalkPackageServiceImpl();
talkService.talk(66, phoneCard);
System.out.println("---------------------------------------------------");
// 4.声明AbstractPackage类型的引用指向NetPackage类型的对象,也就是抽象类引用指向自雷的对象从而形成了多态
AbstractPackage abstractPackage = new NetPackageServiceImpl(5, 30);
abstractPackage.show();
}
}