JavaSE——封装、继承和多态

2024-09-09 05:36
文章标签 java se 封装 继承 多态

本文主要是介绍JavaSE——封装、继承和多态,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

1. 封装

1.1 概念

     面向对象程序三大特性:封装、继承、多态 。而类和对象阶段,主要研究的就是封装特性。何为封装呢?简单来说就是套壳屏蔽细节
    比如:对于电脑这样一个复杂的设备,提供给用户的就只是:开关机、通过键盘输入,显示器, USB 插孔等,让用户来和计算机进行交互,完成日常事务。但实际上:电脑真正工作的却是CPU 、显卡、内存等一些硬件元件。
   对于计算机使用者而言,不用关心内部核心部件,比如主板上线路是如何布局的, CPU 内部是如何设计的等,用户只需要知道,怎么开机、怎么通过键盘和鼠标与计算机进行交互即可。因此计算机厂商在出厂时,在外部套上壳 子,将内部实现细节隐藏起来,仅仅对外提供开关机、鼠标以及键盘插孔等,让用户可以与计算机进行交互即可
  封装:将数据和操作数据的方法进行有机结合,隐藏对象的属性和实现细节,仅对外公开接口来和对象进行交互

  若进行封装就需要使用访问限定符(稍后详细解释)

1.2 封装的实现

 在代码层面就是把用public 修饰的成员变量/方法改为用private 修饰

代码如下:

class Dog{private String name ;private int age ;public Dog(String name, int age) {this.name = name;this.age = age;}public void eat(){System.out.println(this.name + "正在吃饭!");}public static void main(String[] args) {Dog dog = new Dog("小黄",3);System.out.println(dog.name);}
}

在同一个包同一个类中,private 修饰的成员变量/方法 可以被直接访问:

除此之外,其他三种情况下都不可以被直接访问:

不过,我们可以通过 get 和 set 方法对private 修饰的成员变量/方法进行间接访问:

class Dog{private String name ;private int age ;public Dog(String name, int age) {this.name = name;this.age = age;}public String getName() {return name;}public void setName(String name) {this.name = name;}public int getAge() {return age;}public void setAge(int age) {this.age = age;}public void eat(){System.out.println(this.name + "正在吃饭!");}}
public class test1 {public static void main(String[] args) {Dog dog = new Dog("小黄",3);System.out.println(dog.getName());}
}

运行结果如下:

2. 包

2.1 概念

在面向对象体系中,提出了一个软件包的概念,即: 为了更好的管理类,把多个类收集在一起成为一组,称为软件 。有点类似于目录。比如:为了更好的管理电脑中的歌曲,一种好的方式就是将相同属性的歌曲放在相同文件下,也可以对某个文件夹下的音乐进行更详细的分类。

 

  在 Java 中也引入了包, 包是对类、接口等的封装机制的体现,是一种对类或者接口等的很好的组织方式 ,比如:一个包中的类不想被其他包中的类使用。包还有一个重要的作用:在同一个工程中允许存在相同名称的类,只要处在 不同的包中即可

2.2 如何导入包中的类

1. 直接使用包名导入,例如Date类:可以使用 java.util.Date 导入 java.util 这个包中的 Date类.

不过这个使用有点麻烦。

2. 使用 import语句导入包 

这个就方便多了。如果需要使用 java.util 中的其他类, 可以使用 import java.util.*  

不过这样存在一些问题:容易出现冲突的情况.  

这种情况下,需要使用完整的类名

 所以我们更建议显式的指定要导入的类名.

注意事项 :
   import C++ #include 差别很大 . C++ 必须 #include 来引入其他文件内容 , 但是 Java 不需要 .
import 只是为了写代码的时候更方便 . import 更类似于 C++ namespace using

2.3 自定义包

2.3.1 基本规则

  • 在文件的最上方加上一个 package 语句指定该代码在哪个包中.
  • 包名需要尽量指定成唯一的名字, 通常会用公司的域名的颠倒形式(例如 com.dadu.www ).
  • 包名要和代码路径相匹配. 例如创建 com.dadu.www 的包, 那么会存在一个对应的路径 com.dadu.www来存储代码.
  • 如果一个类没有 package 语句, 则该类被放到一个默认包中

2.3.2 操作步骤(以ideal为例)

1. IDEA 中先新建一个包 : 右键 src -> 新建 ->
2. 在弹出的对话框中输入包名 , 例如 com.dadu.www
3. 在包中创建类 , 右键包名 -> 新建 -> , 然后输入类名即可 .
4. 此时可以看到我们的磁盘上的目录结构已经被 IDEA 自动创建出来了
5. 同时我们也看到了 , 在新创建的 Test.java 文件的最上方 , 就出现了一个 package 语句

2.4 控制包访问权限举例

1.访问 public 修饰的变量

2. 访问 private 修饰的变量

报错,因为 name 是私有的,不允许其他的类访问。

3. 访问 default 修饰的变量

报错,因为default 修饰的变量不允许被其他包中的类访问。

2.5 其他的包

1. java.lang: 系统常用基础类 (String Object), 此包从 JDK1.1 后自动导入。
2. java.lang.reflect:java 反射编程包 ;
3. java.net: 进行网络编程开发包。
4. java.sql: 进行数据库开发的支持包。
5. java.util: java 提供的工具程序包。 ( 集合类等 ) 非常重要
6. java.io:I/O 编程开发包。

3.继承

3.1 概念

继承 (inheritance) 机制 :是面向对象程序设计使代码可以复用的最重要的手段,它允许程序员在保持原有类特性的基础上进行扩展,增加新功能 ,这样产生新的类,称 派生类 。继承呈现了面向对象程序设计的层次结构, 体现了由简单到复杂的认知过程。继承主要解决的问题是:共性的抽取,实现代码复用
例如:狗和猫都是动物,那么我们就可以将共性的内容进行抽取,然后采用继承的思想来达到共用。
   上述图示中, Dog Cat 都继承了 Animal 类,其中: Animal 类称为父类 / 基类或超类 Dog Cat 可以称为 Animal 子类/ 派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。
从继承概念中可以看出继承最大的作用就是:实现代码复用,还有就是来实现多态 ( 后序讲 )

3.2 继承的语法

Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下:

修饰符 class 子类 extends 父类 {
// ...
//...
}
我们将上面图中的示例用代码演示一下:
class Animal {public String name;public int age;public void eat(){System.out.println(name + "正在吃饭");}public void sleep(){System.out.println(name + "正在睡觉");}
}class Dog extends Animal{public void bark(){System.out.println(name +"汪汪叫!");}
}
class Cat extends Animal{public void mew(){System.out.println(name +"喵喵叫!");}
}
public class test2{public static void main(String[] args) {Dog dog = new Dog();// dog类中并没有定义任何成员变量,name和age属性肯定是从父类Animal中继承下来的System.out.println(dog.name);System.out.println(dog.age);// dog访问的eat()和sleep()方法也是从Animal中继承下来的dog.eat();dog.sleep();dog.bark();}
}

运行结果如下:

注意:
1. 子类会将父类中的成员变量或者成员方法继承到子类中了
2. 子类继承父类之后,必须要新添加自己特有的成员,体现出与基类的不同,否则就没有必要继承了

3.3 父类成员访问

3.3.1 子类对象访问成员变量

1. 子类和父类不存在同名成员变量

class Data{public int a;public int b;
}
class Num extends Data{public int c;public void func(){a = 10; // 访问从父类中继承下来的ab = 20; // 访问从父类中继承下来的bc = 30; // 访问子类自己的cSystem.out.println(a + " "+b + " " + c);}
}
public class test3 {public static void main(String[] args) {Num n = new Num();n.func();}
}
运行结果如下:
2. 子类和父类成员变量同名
class Data{public int a = 10;public int b = 20;public int c = 30;
}
class Num extends Data{public int c = 60;public void func(){System.out.println(a + " "+b + " " + c);}
}
public class test3 {public static void main(String[] args) {Num n = new Num();n.func();}
}

运行结果如下:

3. 子类和父类都没有同一个变量

通过上述示例我们可知:在子类方法中 或者 通过子类对象访问成员时
  • 如果访问的成员变量子类中有,优先访问自己的成员变量。
  • 如果访问的成员变量子类中无,则访问父类继承下来的,如果父类也没有定义,则编译报错。
  • 如果访问的成员变量与父类中成员变量同名,则优先访问自己的。
成员变量访问遵循就近原则,自己有优先自己的,如果没有则向父类中找

3.3.2 子类对象访问成员方法

1. 子类和父类都没有同一个方法
2. 成员方法名字不同
class Data{public void func1(){System.out.println("Data中的func1方法!");}
}
class Num extends Data{public void func2(){System.out.println("Num中的func2方法!");}public void func3(){func1();func2();}
}
public class test3 {public static void main(String[] args) {Num n = new Num();n.func3();}
}

运行结果如下:

3. 成员方法名字相同
class Data{public void func1(){System.out.println("Data中的func1方法!");}public void func2(){System.out.println("Data中的func2方法!");}
}
class Num extends Data{public void func1( int a){System.out.println("Num中的func1(int)方法!");}public void func2(){System.out.println("Num中的func2方法!");}public void func3(){func1();        // 没有传参,访问父类中的func1()func1(20);   // 传递int参数,访问子类中的func1(int)func2();        // 直接访问,则永远访问到的都是子类中的func2(),基类的无法访问到}
}
public class test3 {public static void main(String[] args) {Num n = new Num();n.func3();}
}

运行结果如下:

通过上述示例我们可知:
  • 通过子类对象访问父类与子类中不同名方法时,优先在子类中找,找到则访问,否则在父类中找,找到则访问,否则编译报错。
  • 通过派生类对象访问父类与子类同名方法时,如果父类和子类同名方法的参数列表不同(重载),根据调用方法适传递的参数选择合适的方法访问,如果没有则报错;

3.4 super 关键字

    由于设计不好,或者因场景需要,子类和父类中可能会存在相同名称的成员,如果要在子类方法中访问父类同名成员时,该如何操作?直接访问是无法做到的,Java 提供了 super 关键字,该关键字主要作用:在子类方法中访问父 类的成员
具体实现代码如下:
class Data{int a;int b;public void func1(){System.out.println("Data中的func1方法!");}public void func2(){System.out.println("Data中的func2方法!");}
}
class Num extends Data{int a;  // 与父类中成员变量同名且类型相同char b; // 与父类中成员变量同名但类型不同// 与父类中func1()构成重载public void func1( int a){System.out.println("Num中的func1(int)方法!");}// 与父类中func2()构成重写public void func2(){System.out.println("Num中的func2方法!");}public void func3(){// 对于同名的成员变量,直接访问时,访问的都是子类的a = 100; // 等价于: this.a = 100;b = 101; // 等价于: this.b = 101;
// 注意:this是当前对象的引用
// 访问父类的成员变量时,需要借助super关键字
// super是获取到子类对象中从基类继承下来的部分super.a = 200;super.b = 201;
// 父类和子类中构成重载的方法,直接可以通过参数列表区分清访问父类还是子类方法func1(); // 没有传参,访问父类中的func1()func1(20); // 传递int参数,访问子类中的func1(int)
// 如果在子类中要访问重写的基类方法,则需要借助super关键字func2(); // 直接访问,则永远访问到的都是子类中的func2(),基类的无法访问到super.func2(); // 访问基类的func2()}
}
public class test3 {public static void main(String[] args) {Num n = new Num();n.func3();}
}

运行结果如下:

在子类方法中,如果想要明确访问父类中成员时,借助 super 关键字即可。
注意事项:
 1. 只能在非静态方法中使用
 2. 在子类方法中,访问父类的成员变量和方法
super的其他用法在后文中介绍。

3.5 子类构造方法

父子父子,先有父再有子,即:子类对象构造时,需要先调用基类构造方法,然后执行子类的构造方法。
代码示例:
class Data{public Data(){System.out.println("Data()");}
}
class Num extends Data{public Num(){System.out.println("Num()");}}
public class test3 {public static void main(String[] args) {Num n = new Num();}
}

运行结果如下:

1. 无参构造
子类构造方法中默认会调用基类的无参构造方法:super(),
用户没有写时,编译器会自动添加,而且super()必须是子类构造方法中第一条语句,并且只能出现一次
示例如下:

2. 有参构造
代码如下:
class Data{public int a;public int b;public Data(int a,int b){this.a = a;this.b = b;}
}
class Num extends Data{public int c;public Num(int a,int b,int c){super(a,b);this.c = c;}public void func(){System.out.println(a + " "+b + " " + c);}
}
public class test3 {public static void main(String[] args) {Num n = new Num(10,20,30);n.func();}
}

运行结果如下:

在子类构造方法中,并没有写任何关于基类构造的代码,但是在构造子类对象时,先执行基类的构造方法,然后执行子类的构造方法,因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子 肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整 ,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整
注意:
1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的 super() 调用,即调用基类构造方法
2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
3. 在子类构造方法中, super(...) 调用父类构造时,必须是子类构造函数中第一条语句。
4. super(...) 只能在子类构造方法中出现一次,并且不能和 this 同时出现

3.6 super 和 this

super this 都可以在成员方法中用来访问:成员变量和调用其他的成员函数,都可以作为构造方法的第一条语句,那他们之间有什么区别呢?
相同点:
1. 都是 Java 中的关键字
2. 只能在类的非静态方法中使用,用来访问非静态成员方法和字段
3. 在构造方法中调用时,必须是构造方法中的第一条语句,并且不能同时存在
不同点:
1. this 是当前对象的引用,当前对象即调用实例方法的对象, super 相当于是子类对象中从父类继承下来部分成员的引用
2. 在非静态成员方法中, this 用来访问本类的方法和属性, super 用来访问父类继承下来的方法和属性
3. 在构造方法中: this(...) 用于调用本类构造方法, super(...) 用于调用父类构造方法,两种调用不能同时在构造方法中出现
4. 构造方法中一定会存在 super(...) 的调用,用户没有写编译器也会增加,但是 this(...) 用户不写则没有

3.7 继承方式

在现实生活中,事物之间的关系是非常复杂,灵活多样,比如:
但在Java中,只支持几种继承方式:

注意:

一般我们不希望出现超过三层的继承关系. 如果继承层次太多, 就需要考虑对代码进行重构了. 如果想从语法上进行限制继承, 就可以使用 final 关键字

3.8 final 关键字

final 关键可以用来修饰变量、成员方法以及类。
1. 修饰变量或字段,表示常量 ( 即不能修改 )
示例如下:
2. 修饰类:表示此类不能被继承
3. 修饰方法:表示该方法不能被重写 ( 后序介绍 )

3.9 继承和组合

和继承类似 , 组合也是一种表达类之间关系的方式 , 也是能够达到代码重用的效果。组合并没有涉及到特殊的语法(诸如 extends 这样的关键字 ), 仅仅是将一个类的实例作为另外一个类的字段。
继承表示对象之间是 is-a 的关系 ,比如:狗是动物,猫是动物
组合表示对象之间是 has-a 的关系 ,比如:汽车

示例如下:

// 轮胎类
class Tire{
// ...
}
// 发动机类
class Engine{
// ...
}
// 车载系统类
class VehicleSystem{
// ...
}
class Car{private Tire tire; // 可以复用轮胎中的属性和方法private Engine engine; // 可以复用发动机中的属性和方法private VehicleSystem vs; // 可以复用车载系统中的属性和方法
// ...
}
// 奔驰是汽车
class Benz extends Car{
// 将汽车中包含的:轮胎、发送机、车载系统全部继承下来
}
组合和继承都可以实现代码复用,应该使用继承还是组合,需要根据应用场景来选择,一般建议:能用组合尽量用组合。

4. 访问限定符

Java 中主要通过类和访问权限来实现封装: 类可以将数据以及封装数据的方法结合在一起 ,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用 Java 中提供了四种访问限定符:

1. 同一个包的同一类
示例如下:

2. 同一个包不同类

示例如下:

3.不同包中的子类

4. 不同包的非子类 

注意:父类中 private 成员变量虽然在子类中不能直接访问,但是也继承到子类中了
拓展:如何使用访问限定符?
我们希望类要尽量做到 "封装", 即隐藏内部实现细节, 只暴露出 必要 的信息给类的调用者.
因此我们在使用的时候应该尽可能的使用 比较严格 的访问权限. 例如如果一个方法能用 private, 就尽量不要用 public.
另外, 还有一种 简单粗暴 的做法: 将所有的字段设为 private, 将所有的方法设为 public. 不过这种方式属于是 对访问权限的滥用, 还是更希望同学们能写代码的时候认真思考, 该类提供的字段方法到底给 "谁" 使用(是类内部自己用, 还是类的调用者使用, 还是子类使用)

5. 多态

5.1 概念

多态的概念:通俗来说,就是多种形态, 具体点就是去完成某个行为,当不同的对象去完成时会产生出不同的状 态。

 

总之,同一件事情,发生在不同对象身上,就会产生不同的结果。

5.2 实现条件

java 中要实现多态,必须要满足如下几个条件,缺一不可:
1. 必须在继承体系下
2. 子类必须要对父类中方法进行重写
3. 通过父类的引用调用重写的方法
多态体现:在代码运行时,当传递不同类对象时,会调用对应类中的方法。
代码示例如下:
class Animal {public String name;public int age;public Animal(String name,int age){this.name = name;this.age = age;}public void eat(){System.out.println(name + "正在吃饭");}
}class Dog extends Animal{public Dog(String name,int age){super(name,age);}@Overridepublic void eat(){System.out.println(name +"正在吃狗粮!!");}
}
class Cat extends Animal{public Cat(String name, int age) {super(name, age);}@Overridepublic void eat(){System.out.println(name +"正在吃猫粮!!");}
}
// =======================================================
public class test2{public static void main(String[] args) {Dog dog = new Dog("小黄",12);Cat cat = new Cat("小花",13);dog.eat();System.out.println("/");cat.eat();}
}

运行结果如下:

5.3 重写

重写(override) 也称为覆盖。重写是子类对父类非静态、非 private 修饰,非 final 修饰,非构造方法等的实现过程进行重新编写, 返回值和形参都不能改变 即外壳不变,核心重写! 重写的好处在于子类可以根据需要,定义特定于自己的行为。 也就是说子类能够根据需要实现父类的方法。

5.3.1 规则

  • 子类在重写父类的方法时,一般必须与父类方法原型一致: 返回值类型 方法名 (参数列表) 要完全一致
  • 被重写的方法返回值类型可以不同,但是必须是具有父子关系的
  • 访问权限不能比父类中被重写的方法的访问权限更低。例如:如果父类方法被public修饰,则子类中重写该方法就不能声明为 protected

  • 父类被staticprivate修饰的方法、构造方法都不能被重写。

  • 重写的方法, 可以使用 @Override 注解来显式指定. 有了这个注解能帮我们进行一些合法性校验. 例如不小心 将方法名字拼写错了 (比如写成 aet), 那么此时编译器就会发现父类中没有 aet 方法, 就会编译报错, 提示无法 构成重写.

5.3.2 设计原则

对于已经投入使用的类,尽量不要进行修改。最好的方式是:重新定义一个新的类,来重复利用其中共性的内容,并且添加或者改动新的内容。
例如:若干年前的手机,只能打电话,发短信,来电显示只能显示号码,而今天的手机在来电显示的时候,不仅仅可以显示号码,还可以显示头像,地区等。在这个过程当中,我们不应该在原来老的类上进行修改,因为原来的 类,可能还在有用户使用 ,正确做法是: 新建一个新手机的类,对来电显示这个方法重写就好了,这样就达到了我 们当今的需求了

5.3.3 机制

1.静态绑定 :也称为前期绑定 ( 早绑定 ) ,即在编译时,根据用户所传递实参类型就确定了具体调用那个方法。典型代表函数重载。
2.动态绑定 :也称为后期绑定 ( 晚绑定 ) ,即在编译时,不能确定方法的行为,需要等到程序运行时,才能够确定具体调用那个类的方法。

5.4 向上转型和向下转型

5.4.1 向上转型

向上转型:实际就是创建一个子类对象,将其当成父类对象来使用,从小范围向大范围的转换。
语法格式:
父类类型  对象名 = new 子类类型 ()

应用场景 :

1. 直接赋值
2. 方法传参
3. 方法返回
示例如下:

向上转型的优点:让代码实现更简单灵活。
向上转型的缺陷:不能调用到子类特有的方法。

5.4.2 向下转型

将一个子类对象经过向上转型之后当成父类方法使用,再无法调用子类的方法,但有时候可能需要调用子类特有的方法,此时:将父类引用再还原为子类对象即可,即向下转型。
代码示例如下:
不过还是存在一些问题的,如:要是animal 指向的是狗,但是将animal 还原为猫呢?
所以 向下转型用的比较少,而且不安全,万一转换失败,运行时就会抛异常。 Java 中为了提高向下转型的安全性,引入 instanceof ,如果该表达式为 true ,则可以安全转换。
本文是作者学习后的总结,如果有什么不恰当的地方,欢迎大佬指正!!!

这篇关于JavaSE——封装、继承和多态的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1150301

相关文章

JVM 的类初始化机制

前言 当你在 Java 程序中new对象时,有没有考虑过 JVM 是如何把静态的字节码(byte code)转化为运行时对象的呢,这个问题看似简单,但清楚的同学相信也不会太多,这篇文章首先介绍 JVM 类初始化的机制,然后给出几个易出错的实例来分析,帮助大家更好理解这个知识点。 JVM 将字节码转化为运行时对象分为三个阶段,分别是:loading 、Linking、initialization

Spring Security 基于表达式的权限控制

前言 spring security 3.0已经可以使用spring el表达式来控制授权,允许在表达式中使用复杂的布尔逻辑来控制访问的权限。 常见的表达式 Spring Security可用表达式对象的基类是SecurityExpressionRoot。 表达式描述hasRole([role])用户拥有制定的角色时返回true (Spring security默认会带有ROLE_前缀),去

浅析Spring Security认证过程

类图 为了方便理解Spring Security认证流程,特意画了如下的类图,包含相关的核心认证类 概述 核心验证器 AuthenticationManager 该对象提供了认证方法的入口,接收一个Authentiaton对象作为参数; public interface AuthenticationManager {Authentication authenticate(Authenti

Spring Security--Architecture Overview

1 核心组件 这一节主要介绍一些在Spring Security中常见且核心的Java类,它们之间的依赖,构建起了整个框架。想要理解整个架构,最起码得对这些类眼熟。 1.1 SecurityContextHolder SecurityContextHolder用于存储安全上下文(security context)的信息。当前操作的用户是谁,该用户是否已经被认证,他拥有哪些角色权限…这些都被保

Spring Security基于数据库验证流程详解

Spring Security 校验流程图 相关解释说明(认真看哦) AbstractAuthenticationProcessingFilter 抽象类 /*** 调用 #requiresAuthentication(HttpServletRequest, HttpServletResponse) 决定是否需要进行验证操作。* 如果需要验证,则会调用 #attemptAuthentica

Spring Security 从入门到进阶系列教程

Spring Security 入门系列 《保护 Web 应用的安全》 《Spring-Security-入门(一):登录与退出》 《Spring-Security-入门(二):基于数据库验证》 《Spring-Security-入门(三):密码加密》 《Spring-Security-入门(四):自定义-Filter》 《Spring-Security-入门(五):在 Sprin

Java架构师知识体认识

源码分析 常用设计模式 Proxy代理模式Factory工厂模式Singleton单例模式Delegate委派模式Strategy策略模式Prototype原型模式Template模板模式 Spring5 beans 接口实例化代理Bean操作 Context Ioc容器设计原理及高级特性Aop设计原理Factorybean与Beanfactory Transaction 声明式事物

Java进阶13讲__第12讲_1/2

多线程、线程池 1.  线程概念 1.1  什么是线程 1.2  线程的好处 2.   创建线程的三种方式 注意事项 2.1  继承Thread类 2.1.1 认识  2.1.2  编码实现  package cn.hdc.oop10.Thread;import org.slf4j.Logger;import org.slf4j.LoggerFactory

JAVA智听未来一站式有声阅读平台听书系统小程序源码

智听未来,一站式有声阅读平台听书系统 🌟 开篇:遇见未来,从“智听”开始 在这个快节奏的时代,你是否渴望在忙碌的间隙,找到一片属于自己的宁静角落?是否梦想着能随时随地,沉浸在知识的海洋,或是故事的奇幻世界里?今天,就让我带你一起探索“智听未来”——这一站式有声阅读平台听书系统,它正悄悄改变着我们的阅读方式,让未来触手可及! 📚 第一站:海量资源,应有尽有 走进“智听

在cscode中通过maven创建java项目

在cscode中创建java项目 可以通过博客完成maven的导入 建立maven项目 使用快捷键 Ctrl + Shift + P 建立一个 Maven 项目 1 Ctrl + Shift + P 打开输入框2 输入 "> java create"3 选择 maven4 选择 No Archetype5 输入 域名6 输入项目名称7 建立一个文件目录存放项目,文件名一般为项目名8 确定