Java接口详解
接口
接口的概念
在现实生活中,接口的例子比比皆是,比如:笔记本上的USB口,电源插座等。
电脑的USB口上,可以插:U盘,鼠标,键盘等所有符合USB协议的设备
电源插座插孔上,可以插:电脑,电视机,电饭煲等所有符合规范的设备
通过上述例子可以看出:接口就是公共行为的规范标准,大家在实现时,只要符合规范标准,就可以通用。在Java中,接口可以看成是:多个类的公共规范,是一种引用数据类型。
语法规则
接口的定义格式与类的定义格式基本相同,将class关键字换成interface关键字,就定义了一个接口。
public interface 接口名称 {//抽象方法public abstract void method1();//public abstract是固定搭配,可以不写public void method2();abstract void method3();void method4();//注意:在接口中上述的写法虽然都是抽象方法,但是更推荐method4,更加简洁
}
提示:
1.创建接口时,接口的命名一般是以大写字母I开头
2.接口的命名一般使用“形容词”词性的单词
3.阿里编码规范中约定,接口中的方法和属性不要加任何修饰符号,保持代码的简洁性
接口使用
接口不能直接使用,必须要有一个“实现类”来“实现”该接口,实现接口中的所有抽象方法
//类和接口的关系:类 implements 接口
public class 类名称 implements 接口名称 {//...
}
注意:子类和父类之间是extends继承关系,类和接口之间是implements实现关系。
举个接口使用的小栗子:
请实现笔记本电脑使用USB鼠标,USB键盘的例子
1.USB接口:包含打开设备,关闭设备的功能
2.笔记本类:包含开机功能,关机功能,使用USB设备的功能
3.鼠标类:实现USB接口,并具备点击功能
4.键盘类:实现USB接口,并具备输入功能
//定义USB接口
interface USB {void openDevice();void closeDevice();
}class Mouse implements USB {@Overridepublic void openDevice() {System.out.println("打开鼠标");}@Overridepublic void closeDevice() {System.out.println("关闭鼠标");}public void click() {System.out.println("鼠标点击");}
}class KeyBoard implements USB {@Overridepublic void openDevice() {System.out.println("打开键盘");}@Overridepublic void closeDevice() {System.out.println("关闭键盘");}public void input() {System.out.println("键盘输入");}
}class Computer {public void powerOn() {System.out.println("打开电脑");}public void powerOff() {System.out.println("关闭电脑");}//定义电脑使用USB设备的方法,通过多态性,根据传入的USB设备的不同完成不同操作public void useDevice(USB usb) {usb.openDevice();//instanceof:比较左右实例的等操作符if(usb instanceof Mouse) {//向下转型:将 USB 类型的参数 usb 转换为 Mouse 类型的引用 mouse。这样就可以在这个方法中使用 mouse 对象的特有方法Mouse mouse = (Mouse)usb;mouse.click();} else if (usb instanceof KeyBoard) {KeyBoard keyboard = (KeyBoard)usb;keyboard.input();}usb.closeDevice();}
}public class TestUSB {public static void main(String[] args) {Computer computer = new Computer();computer.powerOn();Mouse mouse = new Mouse();KeyBoard keyboard = new KeyBoard();computer.useDevice(mouse);System.out.println("===============");computer.useDevice(keyboard);computer.powerOff();}
}
注:instanceof
是 Java 中的一个关键字,用于检查一个对象是否是指定类或其子类的实例。它的语法是:
object instanceof Class
其中,object
是要检查的对象,Class
是指定的类名。
instanceof
返回一个布尔值,如果对象是指定类的实例或其子类的实例,则返回 true
,否则返回 false
。
接口特性
1.接口类型是一种引用类型,但是不能直接new接口的对象
public class TestUSB {public static void main(String[] args) {USB usb = new USB();}
}//Error:USB是抽象的,无法实例化
2.接口中的每一个方法的类型都是public的抽象方法,即接口中方法会被隐式的指定为public abstract(只能是public abstract,其他修饰符都会报错)
public interface USB {private void closeDevice();
}//Error:此处不允许使用修饰符private
3.接口中的方法是不能在接口中实现的(两个方法除外:static 和 abstract修饰的方法),只能由实现接口中的类实现
public interface USB {void openDevice();void closeDevice() {System.out.println("关闭USB设备");}
}//编译失败:因为接口中的方式默认为抽象方法
//Error:接口中的抽象方法不能带有主体
4.重写接口中的方法时,不能使用默认的访问权限
public interface USB {void openDevice();void closeDevice();
//这两个默认都是public修饰的
}public class Mouse implements USB {@Overridevoid openDevice() {System.out.println("打开鼠标");}//这里的方法是默认修饰符//...
}//编译报错:Error:重写USB中的方法时,不能使用默认修饰符
//正在尝试分配更低的访问权限:以前为public
5.接口中可以含有变量,但是接口中的变量会被隐式指定为public static final变量
interface USB {double brand = 3.0;//默认被public static final修饰void openDevice();void closeDevice();
}public class TestUSB {public static void main(String[] args) {System.out.println(USB.brand);//可以直接通过接口访问,说明是静态的//USB = 2.0;//编译报错:无法为最终变量brand分配值//说明brand具有final属性}
}
6.接口中不能有静态代码块和构造方法
7.接口虽然不是类,但是接口编译完成后字节码文件的后缀格式也是.class
8.如果类中没有实现接口中的所有抽象方法,则必须设置为抽象类
9.jdk8中:接口中还可以包含default方法
实现多个接口
在Java中,类和类之间是可以单继承的。一个类只能有一个父类,即Java中不支持多继承,但是一个类可以实现多个接口。下面通过类来表示一组动物
class Animal {protected String name;public Animal(String name) {this.name = name;}
}
另外我们再提供一组接口,分别表示“会飞的”,“会跑的”,“会游泳的”。
interface IFlying {void fly();
}interface IRunning {void run();
}interface ISwimming {void swim();
}
接下来创建几个具体的动物
猫,是会跑的。
public class Cat extends Animal implements IRunning{public Cat(String name) {super(name);}@Overridepublic void run() {System.out.println(this.name + "正在用四条腿跑");}
}
鱼,是会游的。
public class Fish extends Animal implements ISwimming{public Fish(String name) {super(name);}@Overridepublic void swim() {System.out.println(this.name + "正在用鱼鳍游泳");}
}
青蛙,既能跑,又能游(两栖动物)
public class Frog extends Animal implements IRunning, ISwimming{public Frog(String name) {super(name);}@Overridepublic void run() {System.out.println(this.name + "正在往前跳");}@Overridepublic void swim() {System.out.println(this.name + "正在蹬腿游泳");}
}
注意,一个类实现多个接口时,每个接口中的抽象方法都要实现,否则类必须设置为抽象类。
还有一种动物,水陆空三栖,叫做“鸭子”。
public class Duck extends Animal implements IRunning, ISwimming, IFlying {public Duck(String name) {super(name);}@Overridepublic void fly() {System.out.println(this.name + "正在用翅膀飞");}@Overridepublic void run() {System.out.println(this.name + "正在用两条腿跑");}@Overridepublic void swim() {System.out.println(this.name + "正在漂在水上");}
}
上面的代码展示了Java中面向对象编程最常见的用法:一个类继承一个父类,同时实现多个接口。
我们之前学过:继承具有is-a的语义,而接口表达的含义是:具有xxx特性。
猫是一种动物,具有会跑的特性
青蛙也是一种动物,既能跑,也能游泳
鸭子也是一种动物,既能跑,也能游,还能飞
这样设计有什么好处呢?时刻牢记多态的好处,让程序员忘记类型。有了接口之后,类的使用者就不用具体关注具体哪种类型,而只关注某个类是否有某种能力。
例如,现在实现一个方法,叫跑步
public static void walk(IRunning running) {System.out.println("我带着伙伴去跑步");running.run();
}
在这个walk方法内部,我们并不关注到底是哪种动物,只要是会跑的就行。
Cat cat = new Cat("小猫");
//这里只关注猫是否有跑步能力
walk(cat);Frog frog = new Frog("小青蛙");
walk(frog);//执行结果
我带着伙伴去散步
小猫正在用四条腿跑
我带着伙伴去散步
小青蛙正在向前跳
接口间的继承
在Java中,类和类是单继承的,而一个类可以实现多个接口,接口和接口之间可以多继承。即:用接口可以达到多继承的目的
注:
类和接口之间的关系 -> implements 实现
接口和接口之间的关系 -> extends 拓展
interface A {testA();
}interface B extends A {testB();
}//B中具有A的功能
接口之间的继承相当于把多个接口合并到一起。
接口的使用实例
对对象进行比较
public class Student {String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}
}
给定两个学生对象,对它们进行比较(年龄)
Student student1 = new Student("zhangsan",12);Student student2 = new Student("lisi",18);
仔细思考,不难发现,和普通的整数不一样,两个整数是可以直接比较的,因为其大小关系明确。而两个学生对象的大小关系怎么确定?需要额外指定。
让我们的Student类实现Comparable接口,并实现其中的compareTo方法
//引入Comparable接口表明当前类可以比较,并实现其中的compareTo方法
//尖括号内写的是要比较的类型
public class Student implements Comparable<Student>{String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}@Overridepublic int compareTo(Student o) {if(this.age > o.age) {return 1;} else if(this.age == o.age) {return 0;} else {return -1;}}
}
但上面的写法具有一定的缺点,比如更改了需求:不是比较年龄而是比较姓名,上面的方法显然是写死的,只能比较年龄,其他需求无法满足。
所以这时,我们可以另辟蹊径,在类外面实现比较器。
public class Student{String name;int age;public Student(String name, int age) {this.name = name;this.age = age;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +", age=" + age +'}';}/* @Overridepublic int compareTo(Student o) {if(this.age > o.age) {return 1;} else if(this.age == o.age) {return 0;} else {return -1;}}*/
}//比较器(年龄)
class AgeComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.age - o2.age;}
}//比较器(姓名)
class NameComparator implements Comparator<Student> {@Overridepublic int compare(Student o1, Student o2) {return o1.name.compareTo(o2.name);}
}======================
public class Test1 {public static void main(String[] args) {Student student1 = new Student("zhangsan",12);Student student2 = new Student("lisi",18);AgeComparator agecomparator = new AgeComparator();NameComparator namecomparator = new NameComparator();System.out.println(agecomparator.compare(student1, student2));System.out.println(namecomparator.compare(student1, student2));}
}
这样就可以同时比较年龄和姓名了。
那么回顾上述两种比较的方法,可以得出以下结论:
1.两种方法都可以适用于对象的比较
2.方法一侵入性较强:一旦写好了规定的比较方式,那么以后只能以这种方式比较了
3.方法二可以灵活比较,只需要传递需要比较的两个对象就可以了。
Cloneable接口和深拷贝
Java中内置了一些很有用的接口,Cloneable就是其中之一。
Object类中存在一个clone方法,调用这个方法可以创建一个对象的“拷贝”。但是要想合法调用clone方法,必须先实现Cloneable接口,否则就会抛出CloneNotSupportedException异常
public interface Cloneable {}//空接口/标记接口->表明当前类是可以被克隆的
如何使用 ?
1.首先,在你想要实现克隆功能的类中,实现 Cloneable
接口。例如:
public class MyClass implements Cloneable {// 类的成员和方法定义
}
2.然后,重写 Object
类中的 clone
方法,该方法在实现克隆时会被调用。在重写的方法中,调用 super.clone()
来创建一个对象的浅拷贝。
public class MyClass implements Cloneable {// 类的成员和方法定义@Overridepublic Object clone() throws CloneNotSupportedException {return super.clone();}
}
3.最后,当你需要克隆一个对象时,调用对象的 clone
方法即可。需要注意的是,clone
方法返回的是 Object
类型,所以你可能需要进行强制类型转换。例如:
MyClass original = new MyClass();
try {MyClass cloned = (MyClass) original.clone();// 对克隆对象进行操作
} catch (CloneNotSupportedException e) {e.printStackTrace();
}
需要注意的是,
clone
方法默认进行的是浅拷贝,即只复制了对象的引用。如果你需要实现深拷贝(复制对象的内容),你可能需要在clone
方法中自行实现复制对象内容的逻辑。
那么什么又是浅拷贝和深拷贝呢?
让我们来看以下代码,这是一个浅拷贝的举例:
class Money {public double m = 99.99;
}class Person implements Cloneable {public Money money = new Money();@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone();}
}public class TestDemo3 {public static void main(String[] args) throws CloneNotSupportedException{Person person1 = new Person();Person person2 = (Person)person1.clone();System.out.println("通过person2修改前的结果");System.out.println(person1.money.m);System.out.println(person2.money.m);person2.money.m = 13.6;System.out.println("通过person2修改后的结果");System.out.println(person1.money.m);System.out.println(person2.money.m);}
}
执行结果如下:
如上代码,我们可以看到,通过clone,我们只是拷贝了Person对象。但是Person对象中的Money对象,并没有拷贝。通过person2这个引用修改了 m这个值后,person1这个引用访问m的值时,值也发生了改变。这里就是发生了浅拷贝。
举个栗子:这就相当于家里两个人看一个电视,一个人换了台,两个人就一起看另一个台。
那怎么实现深拷贝呢?
深拷贝是指在复制对象时,不仅复制对象本身,还要递归地复制对象内部的所有引用对象。
来看一下代码:
class Money implements Cloneable {public double m = 99.99;@Overrideprotected Object clone() throws CloneNotSupportedException {return super.clone(); // 这里进行浅拷贝,因为 'm' 是基本类型}
}class Person implements Cloneable {public Money money = new Money();@Overrideprotected Object clone() throws CloneNotSupportedException {Person tmp = (Person)super.clone();tmp.money = (Money)this.money.clone();return tmp;}
}public class TestDemo4 {public static void main(String[] args) throws CloneNotSupportedException{Person person1 = new Person();Person person2 = (Person)person1.clone();System.out.println("通过person2修改前的结果");System.out.println(person1.money.m);System.out.println(person2.money.m);person2.money.m = 13.6;System.out.println("通过person2修改后的结果");System.out.println(person1.money.m);System.out.println(person2.money.m);}
}
运行结果:
显然深拷贝使得改动过后只有person2中的m发生了变化,这就是深拷贝。
还是举个栗子:这就相当于两个人不同看两个电视,一个人换台,另一个人看的并没有变化
为了更容易理解,让我们看一下深拷贝和浅拷贝的内存情况吧:
浅拷贝:
深拷贝:
抽象类和接口的区别
抽象类和接口都是Java中多态的最常见的使用方式。都需要重点掌握,同时必须认清两者的区别。
核心区别:抽象类中可以包含普通方法和普通字段,这样的普通方法和普通字段可以被子类直接使用(不必重写),而接口中不能包含普通方法,子类必须重写所有的抽象方法。
再次提醒:抽象类存在的意义是为了让编译器更好的校验。
好了这一期就到这,这应该是作者字数最多的文章,敲得累死,下了。
相关文章:

Java接口详解
接口 接口的概念 在现实生活中,接口的例子比比皆是,比如:笔记本上的USB口,电源插座等。 电脑的USB口上,可以插:U盘,鼠标,键盘等所有符合USB协议的设备 电源插座插孔上,…...

Windows共享文件夹,用户密码访问
Windows共享文件夹,用户密码访问 小白教程,一看就会,一做就成。 1.先创建一个用户 计算机右键----管理----本地用户和组----点击用户进去---右键新建用户 这里以kk为例 2.找到你想共享的文件夹 3.共享-想共享的文件夹---右键---属性---共…...
Mac更新node
查看本机node版本 node -v 删除node相关内存 sudo npm cache clean -f 安装n sudo npm install n -g 更新node版本 sudo n stable // 把当前系统的 Node 更新成最新的 “稳定版本” sudo n lts // 长期支持版 sudo n latest // 最新版 sudo n 18.17.1 // 指定安装版本 可以顺便…...

2023国赛数学建模思路 - 案例:粒子群算法
文章目录 1 什么是粒子群算法?2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法? 粒子群算法(Pa…...

Wireshark数据抓包分析之ARP协议
一、实验目的: 通过wireshark的数据抓包了解这个ARP协议的具体内容 二、预备知识: 1.Address Resolution Protocol协议,就是通过目标IP的值,获取到目标的mac地址的一个协议 2.ARP协议的详细工作过程,下面描述得非常清晰ÿ…...

6个比较火的AI绘画生成工具
随着人工智能技术的发展,市场上出现了越来越多的人工智能图像生成工具。这些人工智能图像生成工具可以自动创建惊人的图像、艺术作品和设计,以帮助设计师和创意人员更快地实现他们的创造性想法。在本文中,我们将推荐7种最近流行的人工智能图像…...
静力水准仪说明介绍
静力水准仪是测量两点间或多点间相对高程变化的仪器。由储液器、高精度芯体和特别定制电路模块、保护罩等部件组成。沉降系统由多个同型号传感器组成,储液罐之间由通气管和通液管相连通,基准点置于一个稳定的水平基点,当测点相对于基准点发生…...
HAProxy 高级功能与配置
HAProxy 高级功能与配置 配置和验证的环境看这篇文章:HAProxy 各种调度算法介绍 一.基于 cookie 的会话保持 使用cookie关键字来配置后端服务器基于 cookie 的会话持久连接。 配置格式 cookie <name> [ rewrite | insert | prefix ] [ indirect ] [ nocache ][ post…...

cuda编程002—流
没有使用同步的情况: #include <stdio.h> #include <cuda_runtime.h>__global__ void test_kernel(){printf("Message from Device.\n"); } void test(){test_kernel<<<1, 1>>>(); } #include <cuda_runtime.h> #i…...

2023年国赛 高教社杯数学建模思路 - 案例:粒子群算法
文章目录 1 什么是粒子群算法?2 举个例子3 还是一个例子算法流程算法实现建模资料 # 0 赛题思路 (赛题出来以后第一时间在CSDN分享) https://blog.csdn.net/dc_sinor?typeblog 1 什么是粒子群算法? 粒子群算法(Pa…...

【C#学习笔记】数据类中常用委托及接口——以List<T>为例
文章目录 List\<T\>/LinkedList \<T\>为什么是神?(泛型为什么是神)一些常见,通用的委托和接口ComparisonEnumerator List<T>/LinkedList <T>为什么是神?(泛型为什么是神࿰…...

idea的断点调试
1、行断点 首先在代码的最左侧点击会显示红色的圆圈 第二步在main方法中右键选中debug run进行运行 会出现下面图片的情况 出现上图之后,点击console 下一步 这个时候就可以看到调试的结果了 6、方法调用栈:这里显示了该线程调试所经过的所有方法&…...

vue和react学哪一个比较有助于以后发展?
前言 首先声明vue和react这两个框架都是很优秀的前端框架,使用的人群下载量上数量也是相当的庞大,这篇文章没有贬低或者攻击任何一个框架的意思,只在于根据答主的问题来对这两个框架做出对比,以方便大家更加清晰的了解到当下vue和…...

【SkyWalking】分布式服务追踪与调用链系统
1、基本介绍 SkyWalking是一个开源的观测平台,官网:Apache SkyWalking; 可监控:分布式追踪调用链 、jvm内存变化、监控报警、查看服务器基本配置信息。 2、SkyWalking架构原理 在整个skywalking的系统中,有三个角色&am…...

Python“牵手”速卖通商品详情API接口运用场景及功能介绍
速卖通电商API接口是针对速卖通提供的电商服务平台,为开发人员提供了简单、可靠的技术来与速卖通电商平台进行数据交互,实现一系列开发、管理和营销等操作。其中包括商品详情API接口,通过这个API接口商家可以获取商品的详细信息,包…...
java调用python脚本的示例
java调用python脚本的示例 import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader;public class JavaCallPythonScript {public static void main(String[] args) {// 调用Python脚本的命令String pythonScriptPath "path/to/y…...
【C语言】柔性数组(可边长数组)
一、介绍 柔性数组(Flexible Array),又称可变长数组。一般数组的长度是在编译时确定,而柔性数组对象的长度在运行时确定。在定义结构体时允许创建一个空数组(例如:arr [ 0 ] ),该数…...

C++信息学奥赛1131:基因相关性
这段代码的功能是比较两个字符串的相似度,并根据给定的阈值判断是否相似。 解析注释后的代码如下: #include <iostream> #include <string> using namespace std;int main() {double bf; // 定义双精度浮点数变量bf,用于存储阈…...
如何保证分布式系统中服务的高可用性:应对 ZooKeeper Leader 节点故障的注册处理策略
推荐阅读 AI文本 OCR识别最佳实践 AI Gamma一键生成PPT工具直达链接 玩转cloud Studio 在线编码神器 玩转 GPU AI绘画、AI讲话、翻译,GPU点亮AI想象空间 资源分享 「java、python面试题」来自UC网盘app分享,打开手机app,额外获得1T空间 https://dr…...

SQL注入之延时注入
文章目录 延时注入是什么?延时注入获取数据库版本号 延时注入是什么? 延时注入就是利用sleep()函数通过if语句判断所写的语句真假,如果为真返回我们想要的东西(例如:数据库的长度,数据库的名字等࿰…...

springboot 百货中心供应链管理系统小程序
一、前言 随着我国经济迅速发展,人们对手机的需求越来越大,各种手机软件也都在被广泛应用,但是对于手机进行数据信息管理,对于手机的各种软件也是备受用户的喜爱,百货中心供应链管理系统被用户普遍使用,为方…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
QMC5883L的驱动
简介 本篇文章的代码已经上传到了github上面,开源代码 作为一个电子罗盘模块,我们可以通过I2C从中获取偏航角yaw,相对于六轴陀螺仪的yaw,qmc5883l几乎不会零飘并且成本较低。 参考资料 QMC5883L磁场传感器驱动 QMC5883L磁力计…...
【RockeMQ】第2节|RocketMQ快速实战以及核⼼概念详解(二)
升级Dledger高可用集群 一、主从架构的不足与Dledger的定位 主从架构缺陷 数据备份依赖Slave节点,但无自动故障转移能力,Master宕机后需人工切换,期间消息可能无法读取。Slave仅存储数据,无法主动升级为Master响应请求ÿ…...
OpenLayers 分屏对比(地图联动)
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 地图分屏对比在WebGIS开发中是很常见的功能,和卷帘图层不一样的是,分屏对比是在各个地图中添加相同或者不同的图层进行对比查看。…...

云原生玩法三问:构建自定义开发环境
云原生玩法三问:构建自定义开发环境 引言 临时运维一个古董项目,无文档,无环境,无交接人,俗称三无。 运行设备的环境老,本地环境版本高,ssh不过去。正好最近对 腾讯出品的云原生 cnb 感兴趣&…...

基于Java+VUE+MariaDB实现(Web)仿小米商城
仿小米商城 环境安装 nodejs maven JDK11 运行 mvn clean install -DskipTestscd adminmvn spring-boot:runcd ../webmvn spring-boot:runcd ../xiaomi-store-admin-vuenpm installnpm run servecd ../xiaomi-store-vuenpm installnpm run serve 注意:运行前…...

关于easyexcel动态下拉选问题处理
前些日子突然碰到一个问题,说是客户的导入文件模版想支持部分导入内容的下拉选,于是我就找了easyexcel官网寻找解决方案,并没有找到合适的方案,没办法只能自己动手并分享出来,针对Java生成Excel下拉菜单时因选项过多导…...
安卓基础(Java 和 Gradle 版本)
1. 设置项目的 JDK 版本 方法1:通过 Project Structure File → Project Structure... (或按 CtrlAltShiftS) 左侧选择 SDK Location 在 Gradle Settings 部分,设置 Gradle JDK 方法2:通过 Settings File → Settings... (或 CtrlAltS)…...
鸿蒙(HarmonyOS5)实现跳一跳小游戏
下面我将介绍如何使用鸿蒙的ArkUI框架,实现一个简单的跳一跳小游戏。 1. 项目结构 src/main/ets/ ├── MainAbility │ ├── pages │ │ ├── Index.ets // 主页面 │ │ └── GamePage.ets // 游戏页面 │ └── model │ …...