方法(函数、过程)
语法
返回值类型 方法名(参数列表){方法体}
返回值类型:该方法必须返回的一个这个类型的对象
当方法不需要返回值时,返回值类型就定义为void
public static int max(int a,int b){
int max = a>b?a:b;//方法名和变量名不会冲突
//return 返回数据,方法结束
return max;
}
void方法中可以写return,但是不能return null
public static void printMax(int a,int b){
//得到最大值
//调用本类中已经定义好的方法
int result = max(a,b);
//打印
System.out.println(result);
return;//仅代表方法结束,终止方法的作用 void方法不能返回包括null的任何值
}
参数
形参:定义方法时,参数列表的参数
实参:调用方法时,实际传入的参数
可变参数:
声明:sum(int... a){ }
参数类型跟着三个点表示这种类型的参数可以有很多个
使用:将可变参数当做数组使用
public static int sum(int... a){
int sum = 0;
for(int item:a){//增强for循环,元素遍历
sum += item;
}
return sum;
}
注意点:
1.一个方法中只能有一个可变参数
2.可变参数必须在参数列表的最后一个
3.数量可变,类型不可变
4.调用可变参数方法,可以使用数组代替
5.可变参数可以不传
方法重载
在同一个类中,方法名相同,参数列表不同即为重载
//定义一个方法,返回一个数组的最大值
public static int max(int[] arr){//重载max()
int max = arr[0];
for(int i=0;i<arr.length;i++){
if(arr[i]>max){
max = arr[i];
}
}
return max;
}
参数列表不同的要素:
1.参数的类型不同
2.参数的个数不同
3.参数的顺序不同
递归
方法调用自身的过程
三要素:递归定义、递归出口(边界)、递归调用
例:阶乘 !99 = 99*98*97*...*1
public static int jiecheng(int num){//阶乘
if(num<=0){
return 0;//0和负数返回0表示错误
}
if(num==1){//递归边界
return 1;
}
return num*jiecheng(num-1);//递归调用
}
排序算法
1.冒泡排序
public static void maopaopaixu(int[] arr){
//比较j趟,最后一个不需要排序
for(int j=0;j<arr.length-1;j++){
//比较一趟,最大值到数组最后
//已经排好的j个元素不需要再重复排序
for(int i=0;i<arr.length-j-1;i++){//数组越界的可能,i+1是最后一个
//前后两个相邻的元素进行比较
//如果前面的元素大,就交换位置
if(arr[i]>arr[i+1]){
int temp = arr[i];
arr[i] = arr[i+1];
arr[i+1] = temp;
}
}
}
}
关于其他的排序算法会另外整理:2.选择排序 3.插入排序 4.快速排序...堆排序..桶排序...
面向对象
类
描述对象
声明属性和方法
在类中定义属性,用来存储数据,又叫做全局变量
public class Staff {//员工类:描述员工
String code;//编号
String sex;//性别
String name;//姓名
BigDecimal salary;//薪资 表示金融相关因为浮点型的精度问题要使用大十进制类BigDecimal
//类中的方法可以直接调用本类中的属性
public void work(){
System.out.println(name+"正在工作");
}
}
浮点类型在计算机中的存储和计算是有一定精度限制的。由于浮点数使用有限的二进制位数来表示,所以在进行精确的金融计算时可能会出现舍入误差或截断误差。
使用BigDecimal进行金融计算可以确保结果的精度和准确性。它通过将数值存储为字符串或整数数组来表示,并提供了一系列方法来执行加减乘除、取余等常见的数值操作,是处理金融相关计算的一种可靠和推荐的方式。
构造方法:对属性进行初始化
1.构造方法没有返回值类型
2.构造方法的方法名和类名一样
3.如果一个类没有定义任何的构造方法,系统会给予一个默认的空的构造方法
4.类中一旦自定义了任意的构造方法,系统给定的默认的构造方法就消失了
通过构造方法设置属性。如果方法有返回值,即使和类同名也不是构造方法,只是普通方法。
局部变量:方法体或代码块中声明的变量
全局变量:在类中声明的变量
就近原则:在同一个代码块中优先找本代码块中的变量。当子类调用继承来的方法时,优先调用父类的方法,如果没有就往上找最近的祖父类调用
当局部变量和全局变量重名的情况下,可以使用this关键字标注全局变量(本类的)
Staff(String name){//重载无参构造方法
//将参数name设置给name属性
this.name = name;
}
Staff(String code,String name,String sex,double salary){//重载
this.code = code;
this.name = name;
this.sex = sex;
this.salary = salary;
}
对象
实例化对象:用new关键字开辟内存空间
//实例化对象 new开辟内存空间
Staff staff = new Staff();//构造方法,构造器
//设置对象的属性 类中声明了哪些属性,对象中就有哪些属性
staff.code = "YG10001";
staff.name = "王大锤";
staff.sex = "男";
staff.salary = 10000;
//每一个对象都是独立的,都有独立的内存空间,互不影响
Staff staffA = new Staff();
staffA.code = "YG10002";
staffA.name = "赵小芳";
staffA.sex = "女";
staffA.salary = 12000;
//调用对象的方法
staff.work();
staffA.work();
关于main方法:运行哪一个类当中的主方法,哪一个类就是主类
面向对象的特征(特性)
封装、继承、多态
1.封装
隐藏细节(属性和方法),不能让其他类随意访问
通过四个访问权限修饰符达到封装的效果
修饰符 | public | protected | default | private |
---|---|---|---|---|
含义 | 公共的 | 受保护的 / 家族性的 | 默认的(不用写) | 私有的 |
访问权限 | 任意 | 子类以及本包下的类 | 本包中 | 本类中 |
本类 | 本包下子类 | 其他包的子类 | 本包下的类 | 其他包的类 | |
---|---|---|---|---|---|
public | √ | √ | √ | √ | √ |
protected | √ | √ | √ | √ | × |
default | √ | √ | × | √ | × |
private | √ | × | × | × | × |
对私有属性的封装,可以通过 getter 和 setter 方法实现外部的设置和获取
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getSex() {
return sex;
}
public void setSex(String sex) {
this.sex = sex;
}
JavaBean 是一种符合特定模式的 Java 类。它是一种可重用的组件,用于构建 Java 应用程序。JavaBean 必须包含无参构造方法,并且可以通过 getter 和 setter 方法访问其属性。它通常用于表示实体类、数据传输对象(DTO)、POJO(Plain Old Java Object)等。JavaBean 是一种轻量级的组件模型,可以通过一些开发工具(如IDE)自动生成代码,使得开发人员可以更快速地创建和使用 JavaBean。
在IDEA工具中,可以通过右键代码 - Generate(或者快捷键Alt+Insert)快捷生成构造方法、getter和setter等
java对大小写敏感
某些情况下可能会通过解析 getName() 方法来得到 name 属性,属性名应小写
2.继承
一个类可以继承父类,子类中就具有父类中定义好的属性和方法
不是所有的属性和方法都能被调用到,public、protected、本包下父类的default
继承的作用:
(1)代码重用
(2)多态实现的基础
注意:
(1)一个子类只能有一个直接父类(单继承)
(2)java支持多重继承(儿子继承父亲,父亲继承爷爷)
继承用关键字 extends
方法重写:子类对父类中继承过来的方法重新定义
可以用 @Override 注解来标识和验证是否是重写的方法
注意:1.重写方法的返回值、方法名、参数列表不能发生变化
2.重写的方法的访问权限只能更开放,不能更闭塞
class Plane{//父类
protected String code;//protected:子类以及本包下的类可以访问到
String color;
public Plane(String code) {
this.code = code;
}
public void fly(){
System.out.println("看,天上有个飞机");
}
}
class BigPlane extends Plane{
//子类继承父类
//子类对父类中继承过来的方法重新定义:方法重写
//可以使用@override注解来验证是否是重写的方法
@Override
public void fly(){
System.out.println("看,天上有个大飞机!!!");
}
}
父子类之间的构造方法:
子类的构造方法中首行必须调用父类的构造方法
默认调用父类的无参构造方法
父类中没有无参构造方法时,子类构造方法中必须明文声明调用父类哪一个构造方法
使用 this 关键字调用本类对象的属性和方法
使用 super 关键字调用父类的构造方法
public BigPlane(String code){
super(code);
}
public BigPlane(String code,String color){
//super(code,color);
super(code);
this.color = color;
}
向上转型:用父类的指针指向子类的对象
调用方法看对象
调用属性看声明
Plane p =new BigPlane("C919");//向上转型:用父类的指针指向子类的对象
p.code = "BBBBB";//修改父类的属性
BigPlane bp2 = (BigPlane)p;//强转成子类BigPlane类型
bp2.code = "CCCCC";//修改子类的属性
p.fly();//调用子类的方法
p.printcode();
属性不能重写,假设父类Plane和子类BigPlane各自定义了一个同名属性code,使用父类的指针p指向了子类的对象,此时p调用的方法是子类BigPlane的方法,但p.code修改的是父类Plane的属性。
父类和子类各自定义的属性相互独立存储,不存在冲突
3.多态
调用方法时可能出现多种结果,叫做多态
多态的分类:
静态多态:重载造成,在类编译时就可以确定调用的是哪个方法
动态多态:重写造成,只有在执行到该行代码时,才能确定执行的是哪个类中的方法
public class EasyE {
//简单工厂设计模式,静态static没有工厂对象
public static Parent getObj(int a){
if(a==1){
return new SonA();
}else if(a==2){
return new SonB();
}else {
return new Parent();
}
}
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int num = scanner.nextInt();
Parent p = getObj(num);//p这个变量可能指向任意一个子类的对象
p.method();//多态:调用方法时可能会出现多种结果
}
}
class Parent{
public void method(){
System.out.println("parent");
}
}
class SonA extends Parent{
public void method(){
System.out.println("SonA");
}
}
class SonB extends Parent{
public void method(){
System.out.println("SonB");
}
}
扩展:
关于类中方法加static
在Java中,类中的方法可以被定义为静态方法(static method)或实例方法(instance method)。它们之间的区别在于调用方式和作用范围。
1. 静态方法(static method):
静态方法是属于整个类的,而不是类的单个实例。静态方法可以直接使用类名来调用,而无需创建类的实例。静态方法一般用于提供通用的工具方法、工具类方法或类级别的操作。静态方法中不能直接访问类的非静态成员变量和非静态方法,只能访问类的静态成员变量和静态方法,也不能使用this关键字。
2. 实例方法(instance method):
实例方法只能通过对象来调用,必须首先创建类的实例对象,然后使用实例对象来调用实例方法。实例方法能直接访问类的非静态成员变量和非静态方法,并可以使用this关键字。实例方法一般用于封装对象的行为和状态,对实例变量进行操作。
public class MyClass {
public static void sum(int a,int b){//静态方法:属于类的
System.out.println(a+b);
}
public void max(int a,int b){//实例方法
System.out.println(a>b?a:b);
}
}
class test{
public static void main(String[] args) {
MyClass.sum(10,20);//直接使用类名调用
MyClass myObject = new MyClass();//需要先创建类的实例
myObject.max(10,20);//使用实例对象来调用
}
}
当需要一个在整个类中通用的方法,而不需要依赖于类的实例时,可以将方法定义为静态方法;当需要操作类的实例变量和实例方法时,应将方法定义为实例方法。
重载和重写的区别
1. 重写(Override)是指子类重新定义父类中的方法,以达到特定的需求。子类在重写父类方法时,方法名称、参数列表和返回类型都必须与父类方法一致。重写是实现多态性的一种表现。
2. 重载(Overload)是指在同一个类中,允许存在多个方法名相同但参数列表不同的方法。重载方法必须具有不同的参数类型、个数或顺序。重载是通过同一方法名传递不同的参数列表以实现不同功能的方式。
因此,重写是子类重新定义父类方法,而重载是同一类中存在多个方法名相同但参数列表不同的方法的情况。二者都是Java中的多态性的表现。
native关键字 本地的
native关键字的作用:表示该函数是在外部语言中实现的,而不是在当前的编程语言中实现的。它通常用于与C或C++等语言进行交互,可以调用外部的函数或库。通过使用native关键字,编程语言可以调用外部语言中的函数,从而实现更高效或特定的功能。