> 技术文档 > 从C/C++到JAVA:有c/c++基础的快速入门java_会c++怎么快速学java

从C/C++到JAVA:有c/c++基础的快速入门java_会c++怎么快速学java

引入:第一个Java程序

public class study { //study是所创建的类名 public static void main(String[] args) { System.out.println(\"Hello World\"); //输入syso按回车就可输出输出语句 } }

Java基础知识

数据类型(跟C语言差不多)

基本数据类型
public class study { public static void main(String[] args) { //基本数据类型 //整数类型 int num1=10;//占四个字节 byte num2=20;//占一个字节 short num3=30;//占两个字节 long num4=40L;//Long类型要在数字后加个L,占八个字节 //整数拓展 int i=10; int i2=010;//八进制:0开头 int i3=0x10;//十六进制:0x开头 //小数(浮点数) float num5=50.1F;//float类型要在数字后面加个F,占四个字节 double num6=3.1415926535;//占八个字节 //字符 char name=\'A\';//占两个字节 //字符串,String不是关键字,是类 String namea=\"从入门到精通\"; System.out.println(name); System.out.println((int)name);//强制转换 //转义字符 // \\t 制表符 System.out.println(\"Hello\\tWorld\"); // \\n换行符 System.out.println(\"Hello\\nWorld\"); //布尔值:是非(true和false) boolean flag=true;//占一个字节 } }
类型转换(自动转换and强制转换)

低 --------------------------------------------------> 高

Byte,short,char-->int-->long-->float-->double

从低到高:自动转换

从高到低:强制转换(在前面加上(要转换的类型)即可)

System.out.println((int)3.14);

*拓展

public class study { public static void main(String[] args) { //JDK7新特性:数字之间可以用下划线分割 int money=10_0000_0000; System.out.println(money); } }

变量

(这里的方法,类等词看不懂可以先记着)

局部变量

与C语言的局部变量相似

  1. 定义位置:在方法体、构造方法内部或者代码块({})中定义的变量。
  2. 作用域:从定义的位置开始,到包含该变量的代码块结束。一旦代码执行离开这个代码块,局部变量就会失效,内存也会被释放。
  3. 初始化要求:没有默认值,在使用前必须显式初始化,否则会编译报错。
  4. 内存分配:存储在栈内存中,随着方法的调用和结束进行创建和销毁。
实例变量
  1. 定义位置:在类中,但在方法、构造方法和代码块之外定义的变量。
  2. 作用域:整个类,对类的所有方法、构造方法都可见。
  3. 初始化要求:有默认值,数值类型默认值为 0(如 int 为 0,double 为 0.0),布尔类型默认值为 false,引用类型默认值为 null。不过也可以在定义时显式初始化,或者在构造方法、代码块中进行初始化。
  4. 内存分配:存储在堆内存中,随着对象的创建而存在,对象被垃圾回收时,实例变量占用的内存也会被释放。
类变量(静态变量)
  1. 定义位置:在类中,使用 static 关键字修饰的变量。
  2. 作用域:整个类,通过类名或者对象名(不推荐,容易造成混淆)都可以访问。
  3. 初始化要求:有默认值,和实例变量的默认值规则相同。可以在定义时显式初始化,也可以在静态代码块中初始化。
  4. 内存分配:存储在方法区(Java 8 及之后的版本,方法区在元空间中),在类加载时就会分配内存,直到程序结束才会被释放,无论是否创建了类的对象,类变量始终存在。
public class study { //实例变量:从属于对象(方法外面,类里面),可以不用初始化 String name; int age; //类变量 static static double salary=2500; //main方法 public static void main(String[] args) { //局部变量:必须声明和初始化 int i=10; } }

常量

初始化后不能再改变值

常量名一般用大写字母:final 常量名=值;

public class study { //修饰符,不存在先后顺序 static final double PI=3.14; final static double PI2=3.14; public static void main(String[] args) { System.out.println(PI); System.out.println(PI2); } }

运算符 

基本跟C语言一样

使用工具类

在 Java 中,Math类是一个位于java.lang包下的工具类,提供了一系列用于执行基本数学运算的静态方法静态常量。由于它位于java.lang包,所以无需额外导入即可使用。

静态常量 

Math类定义了两个常用的静态常量:

  • Math.PI:表示圆周率,是一个近似值,类型为double,通常用于与圆相关的计算,如计算圆的周长(2 * Math.PI * radius)和面积(Math.PI * radius * radius) 。
  • Math.E:表示自然对数的底数,类型为double,在涉及指数函数、对数函数的计算中经常用到。
数值运算方法
  • 绝对值abs方法用于返回参数的绝对值。它有多种重载形式,能处理intlongfloatdouble等数据类型
    int num = -5;int absNum = Math.abs(num); // absNum 的值为 5
  • 向上取整ceil方法返回大于或等于参数的最小整数,返回值类型为double 
    double num = 3.14;double ceilNum = Math.ceil(num); // ceilNum 的值为 4.0
  • 向下取整floor方法返回小于或等于参数的最大整数,返回值类型为double
    double num = 3.99;double floorNum = Math.floor(num); // floorNum 的值为 3.0
  • 四舍五入round方法用于对数值进行四舍五入操作,根据不同的参数类型,有不同的返回类型。如果参数是float,返回int;如果参数是double,返回long
    float num = 3.4f;int roundNum = Math.round(num); // roundNum 的值为 3double num2 = 3.6;long roundNum2 = Math.round(num2); // roundNum2 的值为 4
  • 幂运算pow方法用于计算一个数的幂次方,接收两个double类型的参数,第一个参数是底数,第二个参数是指数,返回结果也是double类型
    double result = Math.pow(2, 3); // 计算 2 的 3 次方,result 的值为 8.0
  • 开方sqrt方法用于计算一个数的平方根,参数和返回值都是double类型
    double num = 16;double sqrtNum = Math.sqrt(num); // sqrtNum 的值为 4.0
  • 立方根cbrt方法用于计算一个数的立方根,参数和返回值都是double类型
    double num = 27;double cbrtNum = Math.cbrt(num); // cbrtNum 的值为 3.0
随机数生成

random方法用于生成一个大于等于 0.0 且小于 1.0 的随机double类型数值。如果要生成指定范围内的随机整数或其他类型的随机数,可以在此基础上进行变换

double randomNum = Math.random(); // 生成 0.0 到 1.0 之间的随机数// 生成 1 到 100 之间的随机整数int randomInt = (int) (Math.random() * 100 + 1); 
 其他

最大值和最小值maxmin方法用于返回两个数值中的最大值和最小值,有多种重载形式,可处理intlongfloatdouble等数据类型。

int num1 = 5;int num2 = 3;int maxNum = Math.max(num1, num2); // maxNum 的值为 5int minNum = Math.min(num1, num2); // minNum 的值为 3

当然这里并不完整,还有其他工具类等待大家更深入的学习。

逻辑运算

和C语言基本一样

public class study { public static void main(String[] args) { //逻辑运算符 boolean a=true; boolean b=false; System.out.println(\"a&&b:\"+(a&&b)); System.out.println(\"a||b:\"+(a||b)); System.out.println(\"!(a&&b):\"+!(a&&b)); } }

输出:

位运算

和C语言基本一样

&和,|或,^异或,~取反,>>右移,<<左移

<<:相当于把数*2

>>:相当于把数/2

eg.2<<3 : 2 --> 0000 0010 --> (< 8=2^3

字符串连接符
public class study { public static void main(String[] args) { int a=10; int b=20; System.out.println(a+b); //字符串连接符:+ 两侧出现String类型,就把整个式子转换成String类型连接 System.out.println(\"\"+a+b); System.out.println(a+b+\"\");//字符串如果在后面,前面会直接进行算数运算 } }

输出:

*修饰符

修饰符类型 可修饰的元素 核心作用 访问修饰符 类、方法、变量、构造方法 控制访问权限(public > protected > 默认 > private) static 变量、方法、代码块、内部类 声明类级别的成员,无需实例即可访问 final 类、方法、变量 类不可继承,方法不可重写,变量不可修改 abstract 类、方法 类为抽象类(不可实例化),方法为抽象方法(需子类重写) synchronized 方法、代码块 保证多线程同步,避免并发问题 volatile 变量 保证多线程环境下变量的可见性 transient 变量 阻止变量被序列化

Java数组

数组的声明和创建

public class study { //变量类型 变量名字=变量的值 public static void main(String[] args) { int[] nums;//java首选方法 int nums2[];//效果相同但不是首选方法,是C和C++语言风格的 nums=new int[10];//创建数组 for(int i=0;i<10;i++) { nums[i]=i+1; }//赋值 for(int i=0;i<10;i++) { System.out.println(nums[i]); }//输出 } }

数组使用

除了用像C那样for循环遍历数组,Java还可以可以用增强型的for循环

public class study { public static void main(String[] args) { int []array= {1,2,3,4,5}; for(int i:array) { System.out.println(i); } } }

如果是二维数组:

public class study { public static void main(String[] args) { int[][] array=new int[11][11]; for(int[] i:array) { for(int j:i) { System.out.print(j+\"\\t\"); } System.out.println(); } } }

*Arrays类

在 Java 中,Arrays 是一个工具类,位于 java.util 包下,提供了一系列静态方法用于操作数组(如排序、搜索、填充、比较等)。它简化了数组的常见操作,避免了手动编写繁琐的循环代码。

import java.util.Arrays;public class study { public static void main(String[] args) { int[] a= {1,2,3,4,90,31,45,6,23}; //打印数组元素 System.out.println(Arrays.toString(a)); //排序 Arrays.sort(a); System.out.println(Arrays.toString(a)); //填充 Arrays.fill(a,0);//将数组a中的数都填充为0 Arrays.fill(a,2,4,1); //将数组中下标2到下标4的位置填充为1(左闭右开,下标2的会被填充,下标4的不会) System.out.println(Arrays.toString(a)); } }

输出:


JAVA流程控制 

用户交互Scanner(相当于C里面的scanf)

  • 创建 Scanner 对象:通常传入 System.in 作为参数,表示从控制台(标准输入流)读取数据:
Scanner scanner = new Scanner(System.in);
  • 读取输入:使用 Scanner 的方法(如 nextInt()nextLine())读取不同类型的输入。
  • 关闭 Scanner:使用完毕后调用 close() 方法释放资源:
scanner.close();
输入字符串

通过Scanner类的next()与nextLine()方式获取输入的字符串,在读取前一般需要使用hasNext()与hasNextLine()判断是否还有输入的数据

使用next:对输入有效字符之前遇到的空白,next()方法会自动将其去掉,只有输入有效字符后才将其后面输入的空白作为分隔符或者结束符

public class study { public static void main(String[] args) { //创建一个扫描器对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println(\"使用next方式接收:\"); //判断用户有没有输入字符串 if(scanner.hasNext()) { //使用next方式接收 String str=scanner.next(); System.out.println(\"输出的内容为:\"+str); } //凡是属于IO流(输入输出)的类如果不关闭会一直占用资源,要养成好习惯用完就关掉 scanner.close(); } }

输出:

使用nextLine:以回车为结束符

public class study { public static void main(String[] args) { //创建一个扫描器对象,用于接收键盘数据 Scanner scanner = new Scanner(System.in); System.out.println(\"使用nextLine方式接收:\"); //判断用户有没有输入字符串 if(scanner.hasNextLine()) { //使用next方式接收 String str=scanner.nextLine(); System.out.println(\"输出的内容为:\"+str); } //凡是属于IO流(输入输出)的类如果不关闭会一直占用资源,要养成好习惯用完就关掉 scanner.close(); } }

输出:

输入整数/浮点数 

scanner.nextInt() / scanner.nextFloat() / scanner.nextDouble() , scanner.hasNextInt() / scanner.hasNextFloat() / scanner.hasNextDouble()以此类推

public class study { public static void main(String[] args) { Scanner scanner = new Scanner(System.in);//从键盘接收数据 int i=0; float f=0.0f; System.out.println(\"请输入整数:\"); if(scanner.hasNextInt()) { i=scanner.nextInt(); System.out.println(\"整数数据:\"+i); } else { System.out.println(\"输入的不是整数数据!\"); } System.out.println(\"请输入小数:\"); if(scanner.hasNextFloat()) { f=scanner.nextFloat(); System.out.println(\"小数数据:\"+f); } else { System.out.println(\"输入的不是小数数据!\"); } scanner.close(); } }

顺序结构

没什么好说的

选择结构(同C语言)

Else if 结构
public class study { public static void main(String[] args) { Scanner scanner=new Scanner(System.in); System.out.println(\"请输入内容:\"); String s=scanner.nextLine(); //equals:判断字符串是否相等 if(s.equals(\"Hello\")) { System.out.println(s); } else { System.out.println(\"End\"); } scanner.close(); } }
switch多选择结构
public class study { public static void main(String[] args) { char grade=\'F\'; switch(grade) { case \'A\': System.out.println(\"优秀\"); break; case \'B\': System.out.println(\"良好\"); break; case \'C\': System.out.println(\"及格\"); break; case \'D\': System.out.println(\"不及格\"); break; default: System.out.println(\"未知等级\"); } } }

循环结构(跟C一样)

while循环,do...while循环,for循环 

for循环还可以用来遍历数组:

public class study { public static void main(String[] args) { int[] numbers= {10,20,30,40,50}; //遍历数组的元素 for(int x:numbers) { System.out.println(x); } } }

eg.九九乘法表

public class study { public static void main(String[] args) { for(int i=1;i<=9;i++) { for(int j=1;j<=i;j++) { System.out.print(j+\"*\"+i+\"=\"+(i*j)+\"\\t\"); } System.out.println(); } } }

*print是输出不换行,println是输出并换行

eg.打印三角形

public class study { public static void main(String[] args) { //打印三角形 for(int i=1;i=i;j--) { System.out.print(\" \"); } for(int j=1;j<=i;j++) { System.out.print(\"*\"); } for(int j=1;j<i;j++) { System.out.print(\"*\");  } System.out.println(); } } }

输出:

break,continue,goto和C一样


Java方法

相当于C里面的函数:

修饰符 返回值类型 方法名(参数类型 参数名){

          ... ...

          方法体

          ... ...

        return 返回值;

}

public class study { //加法 public static int add(int a,int b) { //静态方法:属于类,可直接通过类名调用,无需创建对象,静态方法无法直接调用非静态方法 return a+b; } //main方法 public static void main(String[] args) { int sum = add(1,2); System.out.println(sum); }}

 参数传递

值传递:也就是C里面经常说的形参改变对实参没影响

引用传递:相当于C中传地址改变实参的值(在 Java 中,参数传递只有 “值传递” 一种方式,不存在严格意义上的 “引用传递”。但由于 Java 中存在基本类型和引用类型的区别,导致参数传递时表现出不同的行为,容易被误解为 “引用传递”。)

//引用传递:对象,本质还是值传递public class study { public static void main(String[] args) { Person p=new Person(); System.out.println(p.name);//初始值为null study.change(p); System.out.println(p.name);//p.name被修改为”小白“ } public static void change(Person p) { p.name=\"小白\"; }}//定义了一个Person类,有一个属性:nameclass Person{ String name;}

*类会在后面面向对象里解释

*非静态方法:调用时要先创建对象(这里在后面的面向对象再详细解释):

方法重载 

在同一个类中定义多个同名但参数不同的方法。编译器会根据调用时提供的参数类型、数量或顺序来自动匹配对应的方法。这是 Java 实现静态多态性(编译时多态) 的一种方式。

方法名必须相同,参数列表必须不同(以下至少一项不同),(1.参数类型2.参数数量3.参数顺序),返回类型可以相同或不同(但仅返回类型不同不足以构成重载),访问修饰符和异常声明可以不同

public class Calculator { // 1. 两个整数相加 public int add(int a, int b) { return a + b; } // 2. 三个整数相加(参数数量不同) public int add(int a, int b, int c) { return a + b + c; } // 3. 两个小数相加(参数类型不同) public double add(double a, double b) { return a + b; } // 4. 整数和小数相加(参数顺序和类型不同) public double add(int a, double b) { return a + b; } public static void main(String[] args) { Calculator calc = new Calculator(); System.out.println(calc.add(2, 3)); // 调用两个整数相加的方法,输出5 System.out.println(calc.add(2, 3, 4)); // 调用三个整数相加的方法,输出9 System.out.println(calc.add(2.5, 3.5)); // 调用两个小数相加的方法,输出6.0 System.out.println(calc.add(2, 3.5)); // 调用整数和小数相加的方法,输出5.5 }}

可变参数(不定项参数)

允许方法接收任意数量的同一类型参数,并将其作为数组处理。这为方法调用提供了更大的灵活性,尤其适用于参数数量不确定的场景。

一个方法中只能指定一个可变参数,它必须是方法的最后一个参数。

public class study { public void test(int... i) { System.out.println(i[0]);// 直接访问数组的第1个元素(索引0) System.out.println(i[1]);// 直接访问数组的第2个元素(索引1) } public static void main(String[] args) { study study =new study();// 创建study类的实例 study.test(1,2,3,4,5);// 调用test方法,传递5个参数 }}

*这里有点看不懂没关系,后面有补充

递归(和C一样)

public class study { public static void main(String[] args) { System.out.println(f(5)); } public static int f(int n) { if(n==1) { return n; } else { return n*f(n-1); } }}

面向对象编程(oop)

面向对象编程 是一种编程范式,它将数据(属性)和操作数据的方法(行为)封装为对象,并通过继承、多态和封装等机制来组织代码。面向对象编程模拟了现实世界的事物及其关系,使代码更具模块化、可维护性和可扩展性。

对象是类的实例,包含状态(属性)和行为(方法)

类是对象的蓝图,定义了对象的共同属性和方法。

面向对象编程的本质就是以类的方式组织代码,以对象的方式组织(封装)数据

方法的调用:(这里可以回顾一下前面的方法部分)

图中的代码展示了 Java 中面向对象编程的基础概念,包括类的定义、对象的创建和方法调用。具体来说,代码通过student类和study类演示了以下核心功能:

核心功能

类的定义与实例化

student类封装了一个行为(say()方法),表示 “学生说话” 的动作。

study类的main方法中创建了student类的对象,并调用其方法。

对象交互

通过new student().say()或student Student = new student(); Student.say()的方式,实例化对象并触发其行为。

控制台输出

最终在控制台打印出\"学生说话了\",验证方法调用成功。

类与对象

类和对象是 OOP 的基础,类是对象的 “蓝图”,对象是类的 “实例”

  • 定义:类是对一类事物的抽象描述,包含该类事物的共同属性(数据)和方法(行为)。
  • 语法(Java 示例)
    public class 类名 { // 属性(成员变量) 数据类型 属性名; // 方法(行为) 返回值类型 方法名(参数列表) { // 方法体 }}
    对象
  • 定义:对象是类的具体实例,具有类定义的属性和方法,是内存中的实际存在。
  • 创建对象:使用new关键字调用类的构造器创建对象,语法为:
    类名 对象名 = new 类名(参数); // 如:Student stu = new Student();
  • 对象的使用
    • 访问属性:对象名.属性名(如stu.name
    • 调用方法:对象名.方法名(参数)(如stu.study()

示例:

构造器(Constructor)

构造器是类中用于初始化对象的特殊方法,与类名同名,无返回值。

1. 特点

  • 方法名与类名完全相同,无返回值(连void都不写)。
  • new关键字的本质是调用构造器。
  • 若未手动定义构造器,编译器会自动生成无参构造器;若定义了有参构造器,需手动显式定义无参构造器(否则无法通过new 类名()创建对象)(比如在后面子类构造器默认先调用父类的无参构造,如果此时父类只有有参构造则无法执行,需要手动调用父类的有参构造)

2. 分类

  • 无参构造器:不接收参数,用于初始化对象的默认值
public class Person { private String name; private int age; // 无参构造方法(手动定义) public Person() { name = \"未知\"; age = 0; } // 使用无参构造创建对象 public static void main(String[] args) { Person p = new Person(); // 调用无参构造 System.out.println(p.getName()); // 输出:未知 } }
  • 有参构造器:接收参数,用于自定义初始化对象属性。
public class Person { private String name; private int age; // 有参构造方法 public Person(String name, int age) { this.name = name; // this关键字区分参数和类属性 this.age = age; } // 使用有参构造创建对象 public static void main(String[] args) { Person p = new Person(\"Alice\", 25); // 调用有参构造 System.out.println(p.getName()); // 输出:Alice } }

3. 构造器重载

同一类中可定义多个构造器,只要参数列表(类型、数量、顺序)不同,称为构造器重载,用于灵活初始化对象。

public class Person { private String name; private int age; // 无参构造 public Person() { this(\"未知\", 0); // 调用有参构造 } // 有参构造(姓名) public Person(String name) { this(name, 0); // 调用有参构造 } // 有参构造(姓名和年龄) public Person(String name, int age) { this.name = name; this.age = age; }}

封装(Encapsulation)

封装是指将对象的属性和方法绑定在一起,通过访问控制隐藏内部实现,仅对外提供必要接口。

1. 作用

  • 保护数据不被外部随意修改,提高安全性。

  • 隐藏实现细节,降低代码耦合度。

  • 统一接口,便于维护和扩展。

2. 实现方式

  • 将属性声明为private(私有),限制外部直接访问。

  • 提供publicgetter方法(获取属性值)和setter方法(修改属性值),在方法中可添加逻辑校验。

继承(extends)

在 Java 中,继承(Inheritance) 是面向对象编程的核心特性之一,它允许一个类(子类)继承另一个类(父类)的属性和方法public)(是类和类之间的关系),从而实现代码复用和层次化设计。通过继承,子类可以扩展父类的功能,也可以修改父类的行为。

子类继承父类的publicprotected成员(属性和方法),private成员不可直接访问(需通过父类的getter/setter)。

Java中只有单继承,没有多继承(一个子类只能有一个父类,一个父类可以有多个子类)

例如图中,Student继承了Person中的money属性,say方法

!!!如果是private则无法继承

Student和Teacher都继承了Person,所以Person是父类,Student和Teacher是子类

继承里也经常用上封装

thissuper

关键字 含义 使用场景 this 指代当前对象 访问当前类的属性、方法、构造器(如this.namethis.study()super 指代父类对象 访问父类的属性、方法、构造器(如super.namesuper.eat()

注意:只有当父类的print方法是public,super.print才能调用此方法,如果父类的print方法是private,则super.print也无法调用

->先调用父类的无参构造再调用子类的无参构造

super调用父类的构造方法,必须在构造方法的第一个

super必须只能出现在子类的方法或者构造方法中

super和this不能同时调用构造方法(因为this也会要求在构造方法的第一个)

VS this-->

代表的对象不同:this:本身调用者这个对象  super:代表父类对象的应用

前提:this:没有继承也使用  super:只能在继承条件才可以使用

构造方法:this(); :本类的构造  super(); :父类的构造

方法重写

方法重写是子类对父类中同名方法的重新定义,实现 “同一方法在不同对象中表现不同”,是多态的基础

重写只和非静态方法有关,需要有继承关系,子类重写父类的方法

要求:

1.方法名相同(方法体不同);

2.参数列表相同;

3.修饰符:范围可以扩大不能缩小(Public > Protected > Default > Private)

4.抛出的异常:范围可以缩小但不能扩大:ClassNotFoundException --> Exception

意义:父类的功能,子类不一定需要或者不一定满足

静态方法:

->删去static

非静态方法:

静态方法和非静态方法有很大区别

同时注意重写的方法关键词只能是public

多态

多态是指同一行为(方法)在不同对象上表现出不同的实现,即 “一个接口,多种实现”。

1. 特点

  • 多态是方法的多态,属性无多态。

  • 前提:存在继承关系、子类重写父类方法、父类引用指向子类对象(父类 变量名 = new 子类())。

2. 示例

// 父类public class Animal { public void eat() { System.out.println(\"动物吃东西\"); }}// 子类1public class Cat extends Animal { @Override public void eat() { System.out.println(\"猫吃鱼\"); }}// 子类2public class Dog extends Animal { @Override public void eat() { System.out.println(\"狗啃骨头\"); }}// 测试类public class Test { public static void main(String[] args) { Animal animal1 = new Cat(); // 父类引用指向Cat对象 Animal animal2 = new Dog(); // 父类引用指向Dog对象 animal1.eat(); // 输出:猫吃鱼(调用Cat的eat) animal2.eat(); // 输出:狗啃骨头(调用Dog的eat) }}

Instanceof 引用类型:用于判断一个对象是什么类型,类的引用类型如果同级或者没有父子关系则报错(亲子鉴定)

类型转换:

!!!

1.父类引用指向子类的对象

2.把子类转换为父类,向上转型

3.把父类转换为子类,向下转型,用强制转换

4.方便方法的调用,减少重复的代码

静态(static)

static修饰的成员(属性或方法)属于类本身,而非对象,所有对象共享同一副本

1. 静态属性

  • 属于类,可通过类名.属性名直接访问,无需创建对象。
  • 所有对象共享该属性值,修改一个对象的静态属性会影响所有对象。
//staticpublic class Student { private static int age;//静态的变量 private double score;//非静态的变量 public static void main(String[] args) { Student s1=new Student(); // 静态变量(如 age):属于类本身,所有对象共享同一份数据,可通过 类名。变量名 直接访问。 //非静态变量(如 score):属于对象实例,每个对象有独立的副本,必须通过 对象引用。变量名 访问。 System.out.println(s1.age);//通过对象来调用变量 System.out.println(s1.score);//通过对象来调用变量 System.out.println(Student.age);//类变量:通过类名访问变量 //System.out.println(Student.score);报错, }}

2. 静态方法

  • 属于类,可通过类名.方法名直接调用,无需创建对象。
  • 静态方法中不能直接访问非静态成员(属性 / 方法),但非静态方法可访问静态成员。
//staticpublic class Student { private static int age;//静态的变量 private double score;//非静态的变量 public void run() {} public static void go() {} public static void main(String[] args) { Student s1=new Student(); s1.run();//调用run方法需要new一个Student对象 Student.go();//调用go方法直接调用就行 go();//直接这样用也可以,因为他在当前这个类里 }}

3. 静态代码块

  • static修饰的代码块,在类加载时执行,且仅执行一次,用于初始化静态资源。
  • 执行顺序:静态代码块 → 匿名代码块 → 构造方法
public class Person { { //代码块(匿名代码块) System.out.println(\"匿名代码块\");//初赋值 } static{ //静态代码块 System.out.println(\"静态代码块\"); } public Person() { System.out.println(\"构造方法\"); } public static void main(String[] args) { Person person=new Person(); //执行顺序:1.静态代码块2.匿名代码块3.构造方法 System.out.println(\"=================\"); Person person2=new Person();//静态代码块只执行一次 }}

输出:

抽象类

抽象类是包含抽象方法的类,无法实例化,需通过子类继承并实现抽象方法。

1. 特点

  • abstract修饰,可包含抽象方法(无方法体,需子类实现)和具体方法(有方法体)。
  • 子类必须实现父类的所有抽象方法(否则子类也需声明为抽象类)。
  • 不能实例化,但可声明引用(用于多态)。
// 抽象类public abstract class Shape { // 抽象方法(无方法体) public abstract double getArea(); // 具体方法(有方法体) public void print() { System.out.println(\"面积为:\" + 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; }}

接口

接口是一种特殊的 “规范”,仅定义方法签名(无实现),用于约束类的行为,实现 “多继承” 效果。

1. 特点

  • interface修饰,方法默认是public abstract(可省略),属性默认是public static final(常量)。

  • 类通过implements关键字实现接口,必须实现接口的所有方法。

  • 一个类可实现多个接口(弥补 Java 单继承的限制),接口之间可继承。