꒰˃͈꒵˂͈꒱ write in front ꒰˃͈꒵˂͈꒱
ʕ̯•͡˔•̯᷅ʔ大家好,我是xiaoxie.希望你看完之后,有不足之处请多多谅解,让我们一起共同进步૮₍❀ᴗ͈ . ᴗ͈ აxiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
本文由xiaoxieʕ̯•͡˔•̯᷅ʔ 原创 CSDN 如需转载还请通知˶⍤⃝˶
个人主页:xiaoxieʕ̯•͡˔•̯᷅ʔ—CSDN博客
系列专栏:xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*
我的目标:"团团等我( ◡̀_◡́ ҂)"( ⸝⸝⸝›ᴥ‹⸝⸝⸝ )欢迎各位→点赞 + 收藏⭐️ + 留言+关注(互三必回)!
本文将会系统的详细的介绍关于JAVASE的所有内容,里面也会掺杂一些面试题,希望能够对同样在学习的Java的你带来帮助
首先我们在学习Java时需要提前准备好编译器,博主建议大家使用idea,最主要的原因就是它功能强大,很合适新手使用,但在使用之前我们需要提前准备好配置环境,在这里博主推荐博主之前总结好的教程初识JAVA-CSDN博客
JDK:JDK是 Java 语言的软件开发工具包,主要用于移动设备、嵌入式设备上的java应用程序。JDK是整个java开发的核心,它包含了JAVA的运行环境(JVM+Java系统类库)和JAVA工具。
JRE:
Java运行环境(Java Runtime Environment,简称JRE)是一个软件,由太阳微系统所研发,JRE可以让计算机系统运行Java应用程序(Java Application)。
JRE的内部有一个Java虚拟机(Java Virtual Machine,JVM)以及一些标准的类别函数库(Class Library)。
JVM:
JVM即Java虚拟机,是一种抽象计算机,它有一个指令集,在运行时操作各种内存区域。
而它们三者的关系为下图
标识符不可以使用数字,关键字开头,并且大小写也要严格区分。
abstract |
assert |
boolean |
break |
byte |
case |
catch |
char |
class |
const |
continue |
default |
do |
double |
else |
enum |
extends |
final |
finally |
float |
for |
goto |
if |
implements |
import |
instanceof |
int |
interface |
long |
native |
new |
package |
private |
protected |
public |
return |
strictfp |
short |
static |
super |
switch |
synchronized |
this |
throw |
throws |
transient |
try |
void |
volatile |
while |
关键字 |
含义 |
abstract |
表明类或者成员方法具有抽象属性 |
assert |
断言,用来进行程序调试 |
boolean |
基本数据类型之一,声明布尔类型的关键字 |
break |
提前跳出一个块 |
byte |
基本数据类型之一,字节类型 |
case |
用在switch语句之中,表示其中的一个分支 |
catch |
用在异常处理中,用来捕捉异常 |
char |
基本数据类型之一,字符类型 |
class |
声明一个类 |
const |
保留关键字,没有具体含义 |
continue |
回到一个块的开始处 |
default |
默认,例如,用在switch语句中,表明一个默认的分支。Java8 中也作用于声明接口函数的默认实现 |
do |
用在do-while循环结构中 |
double |
基本数据类型之一,双精度浮点数类型 |
else |
用在条件语句中,表明当条件不成立时的分支 |
enum |
枚举 |
extends |
表明一个类型是另一个类型的子类型。对于类,可以是另一个类或者抽象类;对于接口,可以是另一个接口 |
final |
用来说明最终属性,表明一个类不能派生出子类,或者成员方法不能被覆盖,或者成员域的值不能被改变,用来定义常量 |
finally |
用于处理异常情况,用来声明一个基本肯定会被执行到的语句块 |
float |
基本数据类型之一,单精度浮点数类型 |
for |
一种循环结构的引导词 |
goto |
保留关键字,没有具体含义 |
if |
条件语句的引导词 |
implements |
表明一个类实现了给定的接口 |
import |
表明要访问指定的类或包 |
instanceof |
用来测试一个对象是否是指定类型的实例对象 |
int |
基本数据类型之一,整数类型 |
interface |
接口 |
long |
基本数据类型之一,长整数类型 |
native |
用来声明一个方法是由与计算机相关的语言(如C/C++/FORTRAN语言)实现的 |
new |
用来创建新实例对象 |
package |
包 |
private |
一种访问控制方式:私用模式 |
protected |
一种访问控制方式:保护模式 |
public |
一种访问控制方式:共用模式 |
return |
从成员方法中返回数据 |
short |
基本数据类型之一,短整数类型 |
static |
表明具有静态属性 |
strictfp |
用来声明FP_strict(单精度或双精度浮点数)表达式遵循IEEE 754算术规范 |
super |
表明当前对象的父类型的引用或者父类型的构造方法 |
switch |
分支语句结构的引导词 |
synchronized |
表明一段代码需要同步执行 |
this |
指向当前实例对象的引用 |
throw |
抛出一个异常 |
throws |
声明在当前定义的成员方法中所有需要抛出的异常 |
transient |
声明不用序列化的成员域 |
try |
尝试一个可能抛出异常的程序块 |
void |
声明当前成员方法没有返回值 |
volatile |
表明两个或者多个变量必须同步地发生变化 |
while |
用在循环结构中 |
用于数据类型的关键字有 boolean、byte、char、 double、 float、int、long、new、short、void、instanceof。
用于语句的关键字有break、case、 catch、 continue、 default 、do、 else、 for、 if、return、switch、try、 while、 finally、 throw、this、 super。
abstract、final、native、private、 protected、public、static、synchronized、transient、 volatile。
class、 extends、 implements、interface、 package、import、throws。还有些关键字,如 future、 generic、 operator、 outer、rest、var等都是Java保留的没有意义的关键字。
goto、const、null。它们不是关键字,而是文字。包含Java定义的值。和关键字一样,它们也不可以作为标识符使用。
以上就是Java中的一些关键字,需要注意的是,这些关键字不需要刻意的去背诵它们,在之后的学习之中我们都会使用到他们,随着学习的深入我相信大家都会记住它们并且灵活的使用它们
使用最广泛的整数类型,占4个字节
int的包装类型为Integer
int的取值范围为 -2^31---(2^31)-1
用于处理文件和网络传输等字节级别的数据,占1个字节
byte的包装类型为Byte
byte的取值范围为 -128—127
可以用于节约内存空间的需求,占2个字节
short的包装类型为Short
byte的取值范围为 -2^15----(2^15)-1
用于处理需要较大值的整数计算,占8个字节
long的包装类型为Long
long的取值范围为 -2^63--(2^63)-1
用于科学计算和需要高精度计算的场景,占4个字节
float的包装类型为Float
float的取值范围为 -2^31--(2^31)-1
使用最广泛的浮点数类型,占8个字节
double的包装类型为Double
double的取值范围为 -2^63--(2^63)-1
可以表示任何字符,占2个字节
char的包装类型为Charzcter
char的取值范围为 -2^15--(2^15)-1
是一种只能取两个值(true或false)的数据类型,它主要用于条件判断和布尔运算
boolean的包装类型为Boolean
boolean的取值范围为只能为true或者是falase
int a=10;
byte b=15;
b=a;
像上图,要把int类型的a赋值给byte类型的b,编译器会报错,不能把数据类型大的赋值给数据类型小的,如果是 a=b;那就可以。
假如你想强行把a赋值给b,可以通过强制类型转换,但一般不建议用,因为可能会造成数据泄露
int a=10;
byte b=15;
b=(byte)a;
int a=10;
byte b=15;
int c=a+b;
小于四个字节的数据会被提升成4个字节再运算
在Java中并没有字符串的基本数据类型,只有字符串这个类,其中有包含许多库函数方法,十分简便,在这里就先不过多赘述,在之后的知识点中博主会为大家详细介绍
关于运算符博主就不过的的叙述了,主要需要注意以下几个注意事项以及位运算符,和移位运算符就足够了
除零错误:在进行除法运算时,需要注意被除数是否为零,以避免出现除零错误。
优先级:不同的运算符有不同的优先级,需要根据运算符的优先级来确定运算的顺序。
溢出:在进行运算时,需要注意运算结果是否会溢出,尤其是在使用整数进行运算时。
举例:
int a = 10;
int b = 20;
int c = a & b;
c =0;
4.按位或 |: 如果两个二进制位都是 0, 则结果为 0, 否则结果为 1.
举例:
int a = 10;
int b = 20;
int c = a|b;
c = 30
此运算符位一元运算符,博主就不举例说明,并且在之后的学习中,几乎不怎么使用
写一个函数返回参数二进制中 1 的个数比如: 15 0000 1111 4 个 1
public static void main(String[] args) {
int a = 15;
System.out.println(countOnes(num));
}
public static int countOnes(int num) {
int count = 0;//计数器
while(num != 0) {
count += num & 1;// 检查最低位是否为1
num >>= 1;// 右移一位,继续检查下一位
}
}
结果如下:
注意的地方
在逻辑运算符的表达式后面必须是布尔表达式,以及注意逻辑短路的问题
关于递归的知识点可以参考博主之前的博客一种艺术般的问题解决办法-----递归-CSDN博客在这里就不过多的赘述了,需要注意的一点是,要想熟练的使用递归还需要大家在平常的学习中多使用多感悟
数组(Array)是有序的元素序列。 [1] 若将有限个类型相同的变量的集合命名,那么这个名称为数组名。组成数组的各个变量称为数组的分量,也称为数组的元素,有时也称为下标变量。用于区分数组的各个元素的数字编号称为下标。数组是在程序设计中,为了处理方便, 把具有相同类型的若干元素按有序的形式组织起来的一种形式。 [1] 这些有序排列的同类数据元素的集合称为数组。数组是用于储存多个相同类型数据的集合
数组的下标是从0开始,使用下标可以访问数组里的元素
和c/c++:int arry[]不同的是 Java的表示方式如上图。注意中括号中不可以写上任何数字
和c/c++ 不同的是使用IDEAJava可以使用导Arrays包的方法简化很多关于数组中的一些常规操作现在博主就为大家总结以下几个常用的方法
import java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry = {1,5,9,6,7,9};
System.out.println(Arrays.toString(arry));
}
}
输出结果如下
只需要Array.toString()就可以做到遍历数组的作用
import java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry = {1,5,10,6,7,9};
Arrays.sort(arry);
System.out.println(Arrays.toString(arry));
}
输出结果如下
只需要Array.sort()就可以做到排序数组的作用
import java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry = {1,5,10,6,7,9};
Arrays.fill(arry,1);
System.out.println(Arrays.toString(arry));
}
}
输出结果如下
Arrays.fill()的作用是用指定的值填充数组的所有元素。它接受四个参数:数组,要填充的元素,起始索引和结束索引。起始索引是要填充的起始位置,结束索引是要填充的结束位置(不包括结束位置)。如果不提供起始索引和结束索引,则默认填充整个数组。
如果我们需要填充到指定位置可以如下图
import java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry = {1,5,10,6,7,9};
Arrays.fill(arry,2,5,11);//参数分别为数组名,起始位置,终点位置,填充的元素
System.out.println(Arrays.toString(arry));
}
}
输出结果如下
需要注意的一点是:起始位置到终点位置的下标是左闭右开的
这里也有博主之前整理的二分查找的模板二分查找之红蓝二分查找-CSDN博客
比如我们经常使用的二分查找法也可以通过Arrays类里的方法快速实现
import java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry = {1,2,3,4,5,6,7,8,9};
int k = 7;
int ret = Arrays.binarySearch(arry,k);
System.out.println(ret);
}
}
输出结果如下
import java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry1 = {1,2,3,4,5,6,7,8,9};
int[] arry2 = Arrays.copyOf(arry1,9);//参数为指定的数组名和数组长度
System.out.println("arry1 ="+Arrays.toString(arry1));
System.out.println("arry2 ="+Arrays.toString(arry2));
}
}
输出结果如下
当然我们也可以指定输出数组的长度,可以复制不同长度的新数组,注意:如果指定的长度大于要复制的对象的数组长度,多出来的元素将会被赋初始值即“0”
如图:
mport java.util.Arrays;//导Arrays包时我们要先导入java.util.Arrays类,以便在代码中使用该类提供的方法和功能
public class Study {
public static void main(String[] args) {
int[] arry1 = {1,2,3,4,5,6,7,8,9};
int[] arry2 = Arrays.copyOf(arry1,13);//参数为指定的数组名和数组长度
System.out.println("arry1 ="+Arrays.toString(arry1));
System.out.println("arry2 ="+Arrays.toString(arry2));
}
}
输出结果如下
以上五个就是博主总结的一些常用的使用Arryas类的一些书写代码格式以及一些注意事项
Java中的二维数组是由多个一维数组组成的数组。它可以被认为是一个表格,其中的每个元素都有两个索引,一个用于指定行号,另一个用于指定列号。他的一些注意事项和一维数组差不多除了
数组长度:二维数组的长度是指行数,可以使用数组名.length
来获取二维数组的行数。要获取每一行的列数,可以使用数组名[行索引].length
。
不规则二维数组:Java中的二维数组可以是不规则的,即每一行的列数可以不同。在声明和初始化不规则二维数组时,需要为每一行指定具体的列数。
声明和初始化:要声明一个二维数组,需要指定数组的行数和列数
别的博主就不过多的赘述了
ava是一门纯面向对象的语言(Object Oriented Program,简称OOP),面向对象是一种编程范式,它将程序的组织方式从过程化的思维方式转变为以对象为中心的思维方式。在面向对象编程中,程序被组织成一组相互协作的对象,每个对象都有自己的状态和行为,并且可以通过消息传递来进行交互。面向对象的编程语言提供了类和对象的概念,通过定义类来创建对象,并通过对象之间的交互来实现程序的功能,Java面向对象有三大巨头------封装,继承,多态 。下文博主将一一介绍它们的语法以及优点等等。
封装是面向对象编程中的一个重要概念,指的是将抽象出来的数据和对数据的操作封装在一起,形成一个类(或对象),使其只能通过类(或对象)提供的接口来访问和操作数据,同时隐藏了数据的实现细节,从而达到保护数据的安全和完整性的目的。通过封装,程序员可以将复杂的系统简化并提高代码的可维护性和可扩展性。
封装的目的是保护数据的安全和完整性,同时隐藏数据的实现细节,提高代码的可维护性和可扩展性,具体有以下几个方面的好处:
保护数据的安全和完整性:封装可以将数据隐藏起来,使得外部代码无法直接访问和修改数据,从而防止数据被意外修改或篡改,提高数据的安全性和可靠性。
隐藏实现细节:封装可以隐藏数据的实现细节,将复杂的实现逻辑封装到类的内部,对外部代码来说,只需要关心调用类的接口即可,不必关心类的内部实现,降低了代码的耦合度,提高了代码的可维护性和可读性。
提高代码的可维护性和可扩展性:封装可以将数据和操作进行分离,使得修改数据的实现细节并不会影响对外部接口的调用方式,从而提高了代码的可维护性和可扩展性,方便系统的后续维护和升级。
Java中主要通过类和访问权限来实现封装:类可以将数据以及封装数据的方法结合在一起,更符合人类对事物的认知,而访问权限用来控制方法或者字段能否直接在类外使用。Java中提供了四种访问限定符:
NO | 范围 | private | default(默认) | protected | public |
1 | 同一个包中的同一类 | ☑️ | ☑️ | ☑️ | ☑️ |
2 | 同一个包中的不同类 | ☑️ | ☑️ | ☑️ | |
3 | 不同包中的子类 | ☑️ | ☑️ | ||
4 | 不同包中的非子类 | ☑️ |
说明:访问限定符不仅可以限制成员属性的访问权限也可以限制类的访问权限;一般成员变量由private 所修饰 成员方法由 public所修饰;default :表示的是没有写访问限定符就默认为default所修饰
public class Employee {
private String name; // 将属性进行封装
private String department; // 将属性进行封装
private int age; // 将属性进行封装
public String getName() {
return name; // 只暴露出了获取属性的接口
}
public void setDepartment(String department) {
this.department = department; // 只暴露出了设置属性的接口
}
public void increaseAge() {
age++; // 只暴露出了对属性进行修改的接口
}
}
在这个例子中,将员工的姓名、部门和年龄进行了封装,只在外部暴露了获取姓名和设置部门、增加年龄的接口,从而保护了属性的安全和完整性,同时隐藏了实现细节。
当然以上举得例子只是封装一个小小的优点之一,等和继承与多态结合起来一起使用,你就会发现封装的妙用了
继承是面向对象编程中的一个概念,它指的是一个类可以派生出新的类,新的类可以继承原来类的属性和方法,同时可以在原有基础上增加自己的属性和方法,从而达到代码复用的目的。继承可以通过子类来扩展或者修改父类的功能,提高代码的可维护性和可复用性。在继承关系中,被继承的类被称为父类或基类,继承的类被称为子类或派生类。
首先让我们看一下下面的例子
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(this.name+"正在吃");
}
}
class Dog {
public String name;
public int age;
public void eat() {
System.out.println(this.name+"正在吃");
}
public void Bark() {
System.out.println(this.name+"汪汪叫");
}
}
class Bird {
public String name;
public int age;
public void eat() {
System.out.println(this.name+"正在吃");
}
public void Bugu() {
System.out.println(this.name+"布谷布谷叫");
}
}
从以上代码可以看出我们设计出的了三个类,相信细心的读者们可以发现这三个类有很多共性的地方,代码有很多的重复使用了,而继承就是为了解决这个问题
上述图示中,Dog和Bird都继承了Animal类,其中:Animal类称为父类/基类或超类,Dog和Bird可以称为Animal的子类/派生类,继承之后,子类可以复用父类中成员,子类在实现时只需关心自己新增加的成员即可。
从继承概念中可以看出继承最大的作用就是:实现代码复用,还有就是来实现多态
在Java中如果要表示类之间的继承关系,需要借助extends关键字,具体如下
class Animal {
public String name;
public int age;
public void eat() {
System.out.println(this.name+"正在吃");
}
}
class Dog extends Animal {
public void Bark() {
System.out.println(this.name+"汪汪叫");
}
}
class Bird extends Animal {
public void Bugu() {
System.out.println(this.name+"布谷布谷叫");
}
}
class Animal {
public String name = "小黑";
public int age;
public void eat() {
System.out.println(this.name+"正在吃");
}
}
class Dog extends Animal {
public String name = "旺财";
public void Bark() {
System.out.println(this.name+"汪汪叫");
}
public void func() {
System.out.println(super.name);
}
}
public class Main {
public static void main(String[] args) {
Dog dog = new Dog();
dog.func();
}
}
结果如下
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(this.name+"正在吃");
}
}
class Dog extends Animal {
public Dog(String name, int age, String sex) {
super(name, age);
this.sex = sex;
}
public String sex;
public void Bark() {
System.out.println(this.name+"汪汪叫");
}
public void func() {
System.out.println(super.name);
}
}
因为:子类对象中成员是有两部分组成的,基类继承下来的以及子类新增加的部分 。父子父子肯定是先有父再有子,所以在构造子类对象时候 ,先要调用基类的构造方法,将从基类继承下来的成员构造完整,然后再调用子类自己的构造方法,将子类自己新增加的成员初始化完整 。
注意:
1. 若父类显式定义无参或者默认的构造方法,在子类构造方法第一行默认有隐含的super()调用,即调用基类构造方法
2. 如果父类构造方法是带有参数的,此时需要用户为子类显式定义构造方法,并在子类构造方法中选择合适的父类构造方法调用,否则编译失败。
3. 在子类构造方法中,super(...)调用父类构造时,必须是子类构造函数中第一条语句。
4. super(...)只能在子类构造方法中出现一次,并且不能和this同时出现
super和this是两个关键字,都是用来引用对象或类的,但是它们有不同的作用和用法。
this关键字用于在一个类的方法中引用该类的成员变量、方法或构造函数。通常用于区分成员变量和方法名相同的情况。例如:
public class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
在上述代码中,this.name引用了该类的成员变量name,而非方法中的参数name。
super关键字用于在子类中引用父类的成员变量、方法或构造函数。通常用于在子类中重写父类的方法时,调用父类的方法或调用父类的构造函数。例如:
public class Person{
private String name;
public Person(String name){
this.name = name;
}
public String getName(){
return this.name;
}
}
在上述代码中,super(name)调用了父类Animal的构造函数,而super.eat()调用了父类Animal的eat方法。
1.private 即只能在自己类中被访问,父类中private成员变量虽然在子类中不能直接访问,但是也继承到子类中了
2.default 即默认在同一个包内父类的default成员变量子类可以访问
3.protected 即在同一个包或者不同包的父类成员变量被protected修饰的子类可以访问
4.public 即都可以被访问
在继承中,final
关键字通常用于类、方法或属性上,用来表示其不能被子类继承或重写。
对于类,如果使用了final
关键字修饰,则该类不能被其他类继承。
对于方法,如果使用了final
关键字修饰,则该方法不能被子类重写。
对于属性,如果使用了final
关键字修饰,则该属性不能在子类中被重新赋值。
使用final
关键字有以下几个好处:
可以提高程序的安全性,避免子类对父类的重要方法或属性进行更改。
可以提高程序的性能,因为编译器可以对final
修饰的方法或属性进行优化,减少运行时的开销。
可以使程序的设计更加灵活,因为final
关键字可以限制子类的行为,从而保证代码的正确性和稳定性。
继承和组合是面向对象编程中常用的两种关系。它们的区别如下:
继承是一种“is-a”(是一个)的关系,即子类是父类的一种具体化,子类可以继承父类的属性和方法。而组合是一种“has-a”(拥有一个)的关系,即一个类拥有另一个类的对象作为自己的属性或成员。
继承是静态的关系,即子类在编译期已经确定了继承关系,而组合是动态的关系,即一个类可以在运行时动态地组合其他类的对象。
继承可以方便地实现代码的重用,减少了代码的冗余。但是过多的继承会导致类之间的耦合性增加,影响代码的灵活性。组合能够更灵活地组合各种对象,但是需要更多的代码来处理对象之间的关系。
继承可以直接访问父类的属性和方法,但是如果父类的实现发生改变,子类也需要相应地做出调整。组合需要通过调用对象的方法来访问其属性和方法,但是更容易适应变化。
Java发生多态的条件包括:
继承:多态是通过父类和子类之间的继承关系实现的。
重写:子类必须重写父类的方法,才能实现多态。
向上转型:使用父类的引用指向子类的对象,从而实现多态。
运行时绑定:多态的方法调用在运行时进行绑定,而不是在编译时确定。这意味着程序在运行时才能确定调用的是哪个类的方法。
从上文中我们可以知道发生多态的条件之一就是发生向上转型,那什么是向上转移呢?
向上转型是指将一个子类对象转换为其父类对象的过程,即子类对象赋值给父类类型的变量。这种转型是安全的,因为子类对象具有父类对象所有的属性和方法,因此可以在父类类型的变量中使用。通常向上转型是多态性的基础之一。
举个例子,如果有一个动物类 Animal,和一个子类狗类 Dog,可以这样转型:
Animal animal = new Dog(); // 向上转型,将子类对象赋值给父类对象
//分解写就是
Dog dog = new Dog();
Animal animal = dog;
在这个例子中,Dog 对象 animal 实际上是一个 Animal 类型的变量,但是它仍然可以调用 Dog 类中定义的方法,因为 Dog 类继续了 Animal 类,所以 Dog 类对象拥有 Animal 类的所有属性和方法。
重写(override)是指在子类中实现一个与父类中同名、同参数列表的方法,并且这个方法的访问修饰符不能低于父类中的方法,目的是覆盖父类中的方法实现。在运行时,调用该方法时将优先执行子类中的实现。重写方法可以改变父类中的行为,实现多态性和动态绑定。
class Animal {
public String name;
public int age;
public Animal(String name, int age) {
this.name = name;
this.age = age;
}
/* 4.private*/ /* 1.final*/ /*2.static*/ public void eat() {
System.out.println(this.name+"正在吃....");
}
}
class Dog extends Animal {
public Dog(String name,int age ) {
super(name,age);
}
@Override//重写,建议加上@Override编译器就会检测是否符合重写的语法
public void eat() {
System.out.println(this.name+"正在吃狗粮....");
}
}
class Bird extends Animal {
public Bird(String name, int age) {
super(name, age);
}
@Override//重写
public void eat() {
System.out.println(this.name + "正在吃鸟粮....");
}
}
public class text {
public static void func(Animal animal){
animal.eat();
}
public static void main(String[] args) {
func(new Dog("旺财",2));
func(new Bird("布谷",1));
}
}
// Animal 类定义
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public void makeSound() {
System.out.println("动物发出叫声");
}
}
// Dog 类继承 Animal 类
public class Dog extends Animal {
public Dog(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("汪汪汪");
}
}
// Cat 类继承 Animal 类
public class Cat extends Animal {
public Cat(String name) {
super(name);
}
@Override
public void makeSound() {
System.out.println("喵喵喵");
}
}
// 测试类
public class Main {
public static void main(String[] args) {
Animal dog = new Dog("旺财");
Animal cat = new Cat("咪咪");
dog.makeSound(); // 输出:汪汪汪
cat.makeSound(); // 输出:喵喵喵
}
}
1.如果加上了方法上了关键字 final 就不可以发生重写
2.如果是被stastic 修饰的方法也不可以发生重写
3.被private修饰的方法也不可以被重写
4.注意被除private修饰的方法,子类的权限范围大于父类的权限范围
5.不要把构造方法中方法重写
6.重写,建议加上@Override编译器就会检测是否符合重写的语法
Java中的抽象类是一种特殊的类,它不能被实例化,只能被继承。抽象类用于定义一些通用的属性和方法,但是这些方法并没有具体的实现,需要子类去实现。抽象类的定义使用关键字abstract来修饰,可以包含抽象方法和非抽象方法。
public abstract class Animal {
//和普通的类一样可以创建成员变量,静态成员变量
public String name;
private int age;
protected String sex;
public static int a;
//和普通的类一样可以创建成员方法,静态成员方法
public void func1() {
}
public static void func2() {
}
//和普通类不一样的是抽象类还可以创建抽象方法
//抽象方法要在方法的前面加上关键字abstract 并且没有具体的实现
public abstract void func3();
}
1.抽象类不能被实例化:抽象类不能被直接实例化,因为它包含未实现的抽象方法。只能被用作其他类的父类,子类必须实现抽象方法才能被实例化。
2.子类必须实现抽象方法:如果一个类继承了一个抽象类,它必须实现抽象类中所有的抽象方法,除非子类也声明自己为抽象类。
3.抽象类可以包含非抽象方法:抽象类中可以包含非抽象方法,这些方法有具体的实现。子类可以直接继承这些非抽象方法,也可以选择性地重写它们。
4.抽象类可以包含成员变量和构造方法:与普通类一样,抽象类可以包含成员变量和构造方法。子类可以通过super关键字调用父类的构造方法。
5.抽象类可以被继承:一个抽象类可以被另一个抽象类继承,子类可以继续定义更多的抽象方法,或者实现所有的抽象方法。
抽象类是一种不能被实例化的类,它主要用于定义一些共性的属性和方法,以供其子类继承和实现。抽象类本身并不具备完整的实现,而是通过其子类来完善其方法和属性。因此,抽象类可以被看作是一种模板或者规范,用来约束其子类的行为和结构。
抽象类的存在可以帮助程序员更好地进行代码的组织和设计,通过抽象类可以定义出一些通用的行为和属性,减少了代码的重复性,提高了代码的可维护性和扩展性。同时,抽象类也能够在一定程度上约束了子类的行为,使得程序更加健壮和可靠。
总的来说,抽象类是xiaoxie的JAVA系列专栏——CSDN博客●'ᴗ'σσணღ*编程中非常重要的概念,它能够帮助程序员更好地进行代码的组织和设计,提高代码的复用性和可维护性。因此,对于抽象类的使用,程序员需要深入理解其特性和用法,合理地应用到实际的程序设计中。
接口是指软件系统中不同组件之间互相传递信息的规范和协定。在面向对象编程中,接口用来定义一个类的行为,是类的一种规范化或规范模式。接口中定义了一些方法,但是并不实现,而是由实现该接口的类去实现。
在具体应用中,接口可以描述两个不同的组件之间的交互方式,包括数据格式、协议、参数、返回值等方面的规范。接口可以帮助不同的系统或组件进行互操作,提高软件的可维护性、可扩展性和灵活性。同时,接口的定义还可以帮助开发人员进行模块化的设计和开发,提高代码的复用和可读性。
public interface IFly {
//接口也可以创建成员变量
//不过成员变量 默认的形式为 public static final
//并且需要初始化 因为接口不能实例化对像
String name = " ";
//接口可以创建成员方法
//成员方法被 public abstract 修饰 也可以不写,并且没有方法实现
//实现这个接口的类需要重写接口的这个方法
public void work();
//要写具体的方法实现 需要被 public static 所修饰
public static void work1() {
}
}
其中,InterfaceName
是所定义的接口的名称,// 接口成员
指的是在接口中定义的方法和属性。在接口中定义的方法和属性不包含函数体和实现细节,只是提供了一个对实现类的约束,即定义了实现类必须实现哪些方法和属性。
1. 确保接口的命名具有描述性,能够清晰地表达其功能和用途。
2. 接口的方法和属性应该按照功能进行分组和命名,以便于理解和使用。
3. 接口的设计应该尽量简洁和易于理解,避免过度复杂或冗余的设计。
4. 在设计接口时,需要考虑到未来可能的扩展和变化,以便接口能够灵活地适应需求的变化。
5. 接口的文档应该清晰地描述每个方法和属性的作用和用法,以便其他开发人员能够正确地使用接口。
6. 在实现接口时,需要确保按照接口定义的要求进行实现,以确保接口的一致性和可靠性。
7. 接口的版本管理也是一个重要的考虑因素,需要确保接口的变化不会对已有的实现造成影响。
8. 在使用接口时,需要遵循接口的规范和约定,以确保接口的正确使用和调用。
1.在Java中子类只能继承一个父类,子类却可以实现多个接口
2.抽象类的成员属性和方法和普通类一样 可以创建成员变量和成员方法,而接口的成员属性是被 public stasic final 和 public abstract 所修饰的
接口是一种非常重要的编程概念,它可以帮助开发人员实现代码的模块化和复用,提高代码的可维护性和可扩展性。
接口提供了一种规范化的方式来定义类之间的交互和通信方式,使得不同的类可以通过实现同一个接口来实现相同的功能。这种方式可以大大减少代码的重复和冗余,同时也可以提高代码的可读性和可理解性。
另外,接口还可以帮助开发人员实现代码的解耦和模块化,使得不同的模块之间可以独立开发和测试,从而提高代码的质量和可靠性。同时,接口的使用也可以促进团队合作和代码复用,使得开发效率得到提高。
总之,作为一种重要的编程概念,接口在软件开发中具有非常重要的作用,它可以帮助开发人员实现代码的复用和模块化,提高代码的可维护性和可扩展性,促进团队合作和开发效率的提高。
接口和抽象类都是面向对象编程中的重要概念,它们可以用于实现多态和封装。在某些情况下,将接口和抽象类结合起来使用可以达到更好的效果。
接口和抽象类的区别在于,接口只能定义方法和常量,而抽象类可以定义具体方法和成员变量。因此,可以使用抽象类来实现接口中的某些方法,然后在子类中重写剩余方法。
例如,假设我们有一个图形接口 Shape,其中定义了一个计算面积的方法 getArea()。我们可以将该接口改为抽象类,并提供一个具体方法 getPerimeter() 来计算周长。这样,子类就可以继承抽象类并只需要实现计算面积的方法。
示例代码如下:
public abstract class Shape {
public double getPerimeter() {
return 0;
}
public abstract double getArea();
}
public class Circle extends Shape {
private double radius;
public Circle(double radius) {
this.radius = radius;
}
@Override
public double getArea() {
return Math.PI * radius * radius;
}
@Override
public double getPerimeter() {
return 2 * Math.PI * radius;
}
}
public class Rectangle extends Shape {
private double length;
private double width;
public Rectangle(double length, double width) {
this.length = length;
this.width = width;
}
@Override
public double getArea() {
return length * width;
}
@Override
public double getPerimeter() {
return 2 * (length + width);
}
}
在上面的示例中,我们将 Shape 接口改为抽象类,并添加了一个具体方法 getPerimeter()。子类 Circle 和 Rectangle 继承自 Shape,并实现了 getArea() 方法和重写了 getPerimeter() 方法。
通过这种方式,我们可以在抽象类中实现一些通用的方法,同时还能保留接口的灵活性。这种结合运用可以使代码更加简洁和易于扩展。
String类是Java中非常重要的一个类,它代表字符串。String类是Java中唯一不用new关键字就可以创建对象的类。在Java中,字符串是使用Unicode字符编码表示的。String类有许多方法可以用来操作字符串,例如连接字符串、截取字符串、查找字符串等等。在Java中,字符串是不可变的,这意味着一旦创建了一个字符串,它就不能被修改。如果需要修改字符串,需要创建一个新的字符串对象。字符串具有很高的使用频率,也是Java中非常重要的数据类型之一。
字符串类的相关知识很重要,在面试题或者是笔试题里出现的频率很高,所以需要我们熟练的掌握它。
String s = "hello";
String s1 = new String("hello");
char[] arr = {'h','e','l','l','o'};
String s2 = new String(arr);
方法 | 功能 |
char charAt(int index)
|
返回 index 位置上字符,如果 index 为负数或者越界,抛出
IndexOutOfBoundsException 异常
|
int indexOf(int ch)
|
返回 ch 第一次出现的位置,没有返回 -1
|
int lastIndexOf(int ch)
|
从后往前找,返回 ch 第一次出现的位置,没有返回 -1
|
String replaceAll(String regex, String replacement)
|
替换所有的指定内容
|
String replaceFirst(String regex, String replacement)
|
替换指定内容
|
String[] split(String regex, int limit)
|
将字符串以指定的格式,拆分为 limit 组
|
String[] split(String regex)
|
将字符串全部拆分
|
String substring(int beginIndex)
|
从指定索引截取到结尾
|
String substring(int beginIndex, int endIndex)
|
截取部分内容
|
String trim()
|
去掉字符串中的左右空格 , 保留中间空格
|
String toUpperCase()
|
字符串转大写
|
String toLowerCase()
|
字符串转小写
|
以上就是字符串常用的库函数了,但需要注意的是String是一种不可变对象. 字符串中的内容是不可改变。字符串不可被修改。
ava异常是指在程序运行过程中出现的错误或异常情况,如空指针异常、数组越界异常等。Java异常处理机制可以使程序在出现异常时不会立即崩溃,而是能够通过异常处理机制来捕获异常并进行处理,从而提高程序的健壮性和可靠性。
Java异常处理机制主要包括以下几个方面:
异常类的继承关系:Java中所有异常类都继承自Throwable类,其中又分为Error和Exception两个子类,其中Error表示程序无法处理的错误,Exception表示程序可以处理的异常。
异常处理语句:Java中提供了try-catch-finally语句来处理异常,其中try块中放置可能出现异常的代码,catch块中捕获异常并进行处理,finally块中放置无论是否出现异常都需要执行的代码。
抛出异常:当程序出现异常时,可以通过throw语句手动抛出异常,并在catch块中进行处理。
自定义异常:Java中允许自定义异常类,可以根据业务需求来定义自己的异常类,并在程序中使用。
异常链:Java中的异常可以形成异常链,即一个异常引发另一个异常,可以通过getCause()方法获取异常链中的前一个异常。
总之,Java异常处理机制是保证程序健壮性和可靠性的重要机制之一,掌握好异常处理机制可以帮助程序员更好地处理异常情况,提高程序的稳定性和可维护性
Java Development Kit (JDK): JDK 是 Java 开发工具包,是整个 Java 平台的核心组成部分。它包含了用于开发 Java 应用程序所需的软件开发工具,包括:
总的来说即:JDK包含JRE,而JRE又包含JVM如果你需要编写和编译 Java 代码,你需要安装 JDK;如果你只需要运行 Java 程序,则只需要安装 JRE 即可。而所有的 Java 程序都需要在 JVM 上运行,这就是所谓的“一次编写,到处运行”(Write Once, Run Anywhere, WORA)的特性。
浅拷贝和深拷贝是两种不同的复制对象的方法,它们的主要区别在于是否创建了原始对象中所引用的对象的新副本。以下是它们之间的主要差异:
重载(Overloading)和重写(Overriding)是面向对象编程中的两个重要概念,它们都与方法的定义和使用有关。下面是两者的区别:
总结起来,重载是在同一个类内提供多种实现方式以适应不同的参数类型,而重写则是在继承体系中使得子类能够替换父类的某些行为,从而实现多态性。
this
关键字用于引用当前类的对象实例。它可以用来调用当前对象的方法或访问当前对象的成员变量。this
来区分局部变量与成员变量。this
调用另一个重载的构造器。this
关键字。super
关键字用于引用父类对象实例。它可以用来调用父类的方法或者访问父类的成员变量。super
关键字调用父类的方法实现。super
调用父类的构造器初始化父类的成员变量。this
一样,不能在类的静态方法、静态代码块或声明为静态的变量中使用super
关键字。总结起来,this
关键字是用来引用当前类的对象实例,而super
关键字则是用来引用父类的对象实例。两者都可以用于访问和操作对象的属性和方法,但是分别对应的是当前类和父类。
extends
关键字来表示继承关系。interface
关键字来声明接口。不可变性:
String
:是不可变的。一旦创建了一个String对象,就不能更改其内容。每次对String进行修改都会创建一个新的String对象。StringBuffer
和 StringBuilder
:这两个类的对象可以被多次修改。线程安全性:
String
:由于它的不可变性,因此它是线程安全的。StringBuffer
:是线程安全的,在多线程环境下使用时不需要额外同步。StringBuilder
:是非线程安全的,它在单线程环境下比StringBuffer更快,因为它不需要执行同步操作。性能:
String
:由于每次修改都需要创建新的对象,所以频繁修改字符串时可能会导致大量内存分配和垃圾回收,影响性能。StringBuffer
和 StringBuilder
:它们内部维护一个字符数组,可以通过动态扩展来适应字符串的变化,所以在频繁修改字符串时效率更高。应用场景:
String
:适合于那些不会改变的字符串常量,或者字符串操作不频繁的情况。StringBuffer
:适用于多线程环境下的字符串操作,比如在一个服务器应用程序中处理用户请求。StringBuilder
:适用于单线程环境下的字符串操作,特别是当需要频繁修改字符串且不需要考虑线程安全的时候。总结起来,当你需要处理不变的字符串或只读字符串时,应使用String;如果你需要频繁地修改字符串,并且是在多线程环境中,应使用StringBuffer;如果你在单线程环境中并且希望提高字符串操作的速度,则应使用StringBuilder。
以上就是博主这一个多月学习JAVASE的所有的内容了,希望你能够对你有所帮助,感谢阅读,祝你一天愉快