记几个有意思的面向对象题目
实验6-1
题目描述
定义一个 Card 类,代表与账户关联的银行卡。
要求:
- 包含属性:卡号(cardNumber)、关联账户(linkedAccount)、余额(balance)、卡状态(active)
- 实现方法
generateCard()生成卡号,卡号的生成规则如下:- 固定前缀:6228
- 中间段:利用inkedAccount的hashCode,取模 10^8 保证 8 位,格式化成 8 位十进制,不足前面补 0
输入格式
输入账号编号
输出格式
输出卡号
输入样例
在这里给出一组输入。例如:
123456789
输出样例
在这里给出相应的输出。例如:
622827588661
这个题正好是我的知识点盲区,我对重写hashcode方法及其用法不是那么的会,所以当场就没写出来,的确,我在某些基础知识点方面很有欠缺的,面向对象只是常见的很熟练,有些真的就不熟甚至不会,所以我在系统性学他的用法,小总结如下:
//在示范equals和hashCode方法中,我需要写一个Person类,我们知道在Java中,对象默认继承Object类,
// Object类中的equals方法比较的是两个对象是否相等,Object类中的hashCode方法返回的是对象的哈希值,
// Object类中的hashCode方法返回的是对象的哈希值,二者一般都要重写。
public class Person extends Object{
private String name;
private int age;
public Person() {
super();
}
public Person(String name, int age) {
super();
try {
setName(name);
setAge(age);
} catch (Exception e) {
System.err.println("创建对象失败!" + e.getMessage());
e.printStackTrace();
throw new RuntimeException("对象创建失败!" + e);
}
}
public String getName() {
return name;
}
public void setName(String name) {
if(name==null||name.isEmpty()){
throw new RuntimeException("姓名不能为空!");
}else{
this.name = name;
}
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age<0||age>120){
throw new RuntimeException("年龄无效!");
}else{
this.age = age;
}
}
@Override
public String toString() {//重写toString方法,如果你不重写toString方法,那么打印对象时,打印的是对象的地址。
return "Person [name=" + name + ", age=" + age + "]";
}
@Override
public boolean equals(Object obj) {// 重写 equals 方法,目的是比较两个对象是否相等
if (this == obj)//判断对象是否为同一个对象
return true;
if (obj == null)//判断对象是否为空
return false;
if (getClass() != obj.getClass())//判断对象是否为同一个类
return false;
Person other = (Person) obj;//强转对象,定义出一个Person对象
if (age != other.age)//判断年龄是否相等
return false;
if (name == null) {//判断姓名是否为空
//在上述情况下,名字要么为空,要么就和形参 other.name 相等
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}
@Override
public int hashCode() { // 重写 hashCode 方法,目的是根据对象的属性计算出一个唯一的整数(哈希值)
// 定义一个质数 31。
// 为什么是 31?因为它是奇素数,能减少哈希冲突,且 JVM 能将其乘法运算优化为位移运算 (i << 5) - i,性能极高。
final int prime = 31;
// 初始化一个非零的起始值。
// 如果初始为 0,第一个参与计算的字段会被“吞掉”(0 * 31 = 0),导致哈希分布不均匀。
int result = 1;
// 将基本数据类型字段(age)加入哈希计算。
// 核心公式:result = 31 * 上一次的 result + 当前字段的值
result = prime * result + age;
// 将引用类型字段(name)加入哈希计算。
// 这里做了一个极其重要的防御性编程:如果 name 为 null,则用 0 代替,防止空指针异常(NullPointerException)。
result = prime * result + ((name == null) ? 0 : name.hashCode());
// 返回最终计算出的哈希值
return result;
}
}
不过实际上我们在计算哈希值的时候,可以直接调方法,如对象.hashcode();这是直接调用了他的object自带方法,所以这道题的代码就好写了,不过还有一个坑,先看代码:
import java.io.*;
import java.util.*;
public class Main {
public static class Card {
public String cardNumber;
public String linkedAccount;
public int balance = 0;//初始化我们的余额就是0
public boolean active = true;
public Card(String linkedAccount) {//带参构造
this.linkedAccount = linkedAccount;
}
public void generateCard() {
String prefix = "6228";
int hash = linkedAccount.hashCode();
//这个计算num的是为了防止负数的出现,就是利用了同余原理
//在同余原理中,同余原理就是防止在数字量过大是时爆掉此数据类型,同时起到防负数的影响的作用
//公式为(a + b) % m = (a % m + b % m) % m
//不过他为什么可以去除负数的影响?
//举个例子就如果说如果我们生成的哈希值是负的,那直接模出来的就会为负,那我们加上一个模数,但模出来的小数位还是不变的,但却可以去除负数的影响
int num = (hash % 100000000 + 100000000) % 100000000;
String middle = String.format("%08d", num);
this.cardNumber = prefix + middle;
}
}
public static void main(String[] args)throws IOException {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
PrintWriter out = new PrintWriter(System.out);
String linkedAccountInput =br.readLine().trim();
Card card = new Card(linkedAccountInput);
card.generateCard();
out.println(card.cardNumber);
out.flush();
br.close();
out.close();
}
}
6-2ATM加密接口
题目描述
定义接口 Encryptable,声明 encrypt(String data) -> String,利用base64进行数据加密。
定义ATM类,并实现取款功能drawal(),按面额优先给出最优解。面额包括:100、50、20、10。
对输出的面额详情进行加密,例如对“100元+3张”进行加密输出
输入格式
输入取款金额
输出格式
输出加密的取款详情
输入样例
在这里给出一组输入。例如:
100
输出样例
在这里给出相应的输出。例如:
MTAw5YWDKzHlvKA=
这个题,我在一开始是没看懂题的,只能说我的知识面它窄了,我们先要知道base64是什么:

不过它怎么编码的其实不重要,根据题目来然后了解基本用法就行
①首先在使用他之前要导包import java.util.Base64;
②第二它可以对二进制转为编码:
String str="Hello123";
byte[] bytes = str.getBytes();//用转换字节把他变为二进制
String encode = Base64.getEncoder().encodeToString(bytes);//直接用就行
那代码如下:
import java.util.*;
import java.io.*;
interface Encryptable{
String encrypt(String data);
}
class ATM implements Encryptable{
@Override
public String encrypt(String data) {
return Base64.getEncoder().encodeToString(data.getBytes());
}
public void drawal(int n){
StringBuilder sb = new StringBuilder();
PrintWriter out = new PrintWriter(System.out);
int[] money = {100,50,20,10};//就是简单的贪心
for(int i=0;i<4;i++) {
if(n>=money[i]) {//在大于此面额的时候,我们才进行此次换算
int temp =n/money[i];
String s=money[i]+"元+"+temp+"张";
out.println(encrypt(s));
n%=money[i];
}
}
}
}
public class Main {
public static void main(String[] args) {
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
int money = 0;
try {
money = Integer.parseInt(br.readLine().trim());
} catch (IOException e) {
throw new RuntimeException(e);
}
ATM atm = new ATM();
atm.drawal(money);
}
}
最后要补充面向对象中的工具instanceof,首先我们要知道它的作用:判断一个对象 到底是什么类型(专门用于多态 / 父类引用指向子类对象的场景)代码如下:
我们先定义一个Animal类做父类:
public class Animal {
public void behavior() {
System.out.println("我是父类的behavior方法");
}
}
定义猫Cat类继承:
public class Cat extends Animal{
@Override
public void behavior(){//重写父类的behavior方法
System.out.println("猫在睡觉");
}
public void meow(){
System.out.println("喵喵喵~~~");
}
}
定义狗Dog类继承:
public class Dog extends Animal{
@Override
public void behavior(){
System.out.println("狗在睡觉");
}
public void bark(){
System.out.println("汪汪汪~~~");
}
}
定义猪Pig类继承:
public class Pig extends Animal{
@Override
public void behavior(){
System.out.println("猪在睡觉");
}
public void oink(){
System.out.println("哼哼哼~~~");
}
}
定义鸭子类Duck继承:
public class Duck extends Animal{
@Override
public void behavior(){
System.out.println("鸭在水中休息");
}
public void quack(){
System.out.println("嘎嘎嘎~~~");
}
}
定义鸟Bird类继承:
public class Bird extends Animal{
@Override
public void behavior(){
System.out.println("鸟在树上休息");
}
public void chirp(){
System.out.println("叽叽叽~~~");
}
}
最后在主测试类里测试,代码如下:
public class Main{
public static void main(String[] args){
Animal []animals=new Animal[5];//定义一个动物类数组
animals[0]=new Bird();
animals[1]=new Cat();
animals[2]=new Dog();
animals[3]=new Bird();
animals[4]=new Duck();
for(Animal animal:animals){
animal.behavior();
}
for (Animal animal : animals) {//判断他的类型然后强转
if (animal instanceof Bird) {
((Bird) animal).chirp();
} else if (animal instanceof Cat) {
((Cat) animal).meow();
} else if (animal instanceof Dog) {
((Dog) animal).bark();
} else if (animal instanceof Duck) {
((Duck) animal).quack();
}
}
}
}
总结一下,对我来说在学习的过程中确实会有很多遗漏的知识点没能掌握,也有很多学过的知识点容遗忘,但是多写代码对知识点的记忆是会有很大益处的,现在是计科的学生,以后成为码农后,代码的敲击是要日复一日来提升自己的,虽然说有AI的帮助,但自己会了才是真的会,没办法,学识浅薄,仍需努力!
AtomGit 是由开放原子开源基金会联合 CSDN 等生态伙伴共同推出的新一代开源与人工智能协作平台。平台坚持“开放、中立、公益”的理念,把代码托管、模型共享、数据集托管、智能体开发体验和算力服务整合在一起,为开发者提供从开发、训练到部署的一站式体验。
更多推荐

所有评论(0)