方法的可变参数

  • 一个方法只能定义一个可变参数
  • 一个方法中其他参数只能放可变参数的前面
  • 可变参数传值时可传入数组
  • 可变参数使用时当成数组使用

方法的可变参数使用

在方法中定义可变参数后,我们可以像操作数组一样操作该参数。

这里,我们就对前面小节的需求使用方法的可变参数进行实现。

public class VariableParamTest {public static void main(String[] args) {int rs1= getSum();System.out.println(rs1);int rs2= getSum(1,2);System.out.println(rs2);    }// 定义一个可变参数方法,求取n个整数之和public static int getSum(int... numbers) {int sum=0;for (int i = 0; i < numbers.length; i++) {sum+=numbers[i];}return sum;}
}

递归方法

递归介绍

递归算法(英语:recursion algorithm)在计算机科学中是指一种通过重复将问题分解为同类的子问题而解决问题的方法。递归式方法可以被用于解决很多的计算机科学问题,因此它是计算机科学中十分重要的一个概念。绝大多数编程语言支持函数的自调用,在这些语言中函数可以通过调用自身来进行递归。计算理论可以证明递归的作用可以完全取代循环,因此在很多函数编程语言(如Scheme)中习惯用递归来实现循环。

递归往往能给我们带来非常简洁非常直观的代码形势,从而使我们的编码大大简化,然而递归的思维确实很我们的常规思维相逆的,我们通常都是从上而下的思维问题, 而递归趋势从下往上的进行思维。这样我们就能看到我们会用很少的语句解决了非常大的问题,所以递归策略的最主要体现就是小的代码量解决了非常复杂的问题。

场景说明:

假设你在一个电影院,你想知道自己坐在哪一排,但是前面人很多,你懒得去数了,于是你问前一排的人「你坐在哪一排?」,这样前面的人 (代号 A) 回答你以后,你就知道自己在哪一排了——只要把 A 的答案加一,就是自己所在的排了,不料 A 比你还懒,他也不想数,于是他也问他前面的人 B「你坐在哪一排?」,这样 A 可以用和你一模一样的步骤知道自己所在的排。然后 B 也如法炮制,直到他们这一串人问到了最前面的一排(或者说问到了知道自己是哪一排的人,预示着调用结束),第一排的人告诉问问题的人「我在第一排」,最后大家就都知道自己在哪一排了。

定义: 一个方法在执行过程中调用自身, 就称为 “递归”。

递归,相当于数学上的 “数学归纳法”, 有一个起始条件, 然后有一个递推公式. 例如, 我们求 N! 起始条件: N = 1 的时候, N! 为 1. 这个起始条件相当于递归的结束条件。

为什么要用递归?

递归可以实现简单代码实现复杂功能

递归的缺点

  • 难以理解
  • 递归方法一定要有出口,否则无限递归调用,直到出现StackOverflowError(栈内存溢出)错误;
  • 递归次数过多会出现栈溢出问题

递归使用

递归的思想就是,通过重复将问题分解为同类的子问题而解决问题的方法。也就是说,针对同样的工作,我们可以定义一个方法,然后重复调用即可。

这里,我们以一个求n的阶乘为例进行说明。

求 N! , 直接不好求, 可以把问题转换成 N! => N * (N-1)!,也就是可以用递归实现。(当前数*前一个数的阶乘)

实例:

public class RecursiveTest {public static void main(String[] args) {// 调用递归方法,求n的阶乘int res=getRecursive(5);System.out.println(res);  }// 递归方法,求n的阶乘public static int getRecursive(int n) {if(n==1) { // 如果为1的时候,就跳出,不再递归return 1;}else {// n非1的情况下,继续调用本身,获取前一个数的递归结果int res=n*getRecursive(n-1);return res;}}
}

图解:

使用循环替代递归方法

这里,我们对前面的求n的阶乘方法使用循环的方式实现。

示例:

public class RecursiveTest2 {public static void main(String[] args) {// 调用递归方法,求n的阶乘int res=getRecursive(6);System.out.println(res); }// 使用循环实现n!public static int getRecursive(int n) {int res=1;for (int i = 1; i <=n; i++) {res*=i;}return res;}
}

递归实现二分查找

案例需求:

  • 使用递归算法,完成一个有序数组的某个元素的二分查找,并打印结果。

思路:

  • 定义有序数组;
  • 定义二分查找方法,注意参数,在方法中控制出口,以及重复递归调用的条件;

代码实现:

public class BinarySearchTest {public static void main(String[] args) {// 定义一个有序数组 int[] arr = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};// 调用递归算法查找元素位置int key=4;int index= binSearch(arr, 0, arr.length-1, key);// 输出结果System.out.println(key+"数字在数组的角标位置是:"+index);}// 定义递归二分算法public static int binSearch(int arr[], int start, int end, int key) {int mid = start + (end - start) / 2;// 找到对应元素if (arr[mid] == key) {return mid;}if (key > arr[mid]) {// 递归调用二分查找return binSearch(arr, mid + 1, end, key);} else if (key < arr[mid]) {// 递归调用二分查找return binSearch(arr, start, mid - 1, key);            }// 没有找到,返回-1标志if (start >= end) {return -1;}return -1;}
}

兔子数列

案例需求:

  • 一般而言,兔子在出生两个月后,就有繁殖能力,一对兔子每个月能生出一对小兔子来。如果所有兔子都不死,那么一年以后可以繁殖多少对兔子?

案例分析:

  • 第一个月小兔子没有繁殖能力,所以还是一对;
  • 两个月后,生下一对小兔子,总数共有两对;
  • 三个月以后,老兔子又生下一对,因为小兔子还没有繁殖能力,总数共是三对;
  • 依次类推。

月数

1

2

3

4

5

6

7

8

9

10

11

12

当月新出生兔子对数

0

0

1

1

2

3

5

8

13

21

34

55

当月总数量

1

1

2

3

5

8

13

21

34

55

89

144

从上述规律可以看出,每个月的兔子对数为:1、1、2、3、5、8、13、21、……,而这个数列就是有名的斐波纳契数列,又称黄金分割数列。

思路:

  • 这个数列的第1和2项属于固定值,F(1)=1,F(2)=1,;
  • 从第三项开始,F(n)=F(n - 1)+F(n - 2),可以使用递归实现,并要有一个出口;

代码实现:

public class FibonacciSequenceTest {public static void main(String[] args) {// 调用方法,获取12个月后的对数int total =fun(12);System.out.println("一年后兔子总对数是:"+total);}// 定义递归放获取对应月数的兔子总对数public static int fun(int m){if(m==1 || m==2) {return 1;}else {// 递归调用,求取前2个月对数之和return fun(m-1)+fun(m-2);}}
}

构造方法

构造方法介绍

定义:就是类构造对象时调用的方法,主要用来实例化对象。构造方法分为无参构造方法、有参构造方法。

构造方法是Java中一个特殊的方法,主要作用是用来构造对象,并初始化对象的属性值。

说明:

  • 构造方法是类的一个特殊成员方法;

  • 构造方法作用:(1)构造出来一个类的实例 (2)对构造出来个一个类的实例(对象)初始化;

  • 构造方法的名字必须与定义他的类名完全相同,没有返回类型,甚至连void也没有;

  • 类中必定有构造方法,若不写,系统自动提供一个无参构造方法;而一旦提供了有参构造方法,就不再提供默认的无参构造方法;

  • 构造方法存在重载,比如无参构造方法和有参构造方法;

  • 构造方法就是来创建对象的,使用new关键字,然后根据提供的构造方法进行选择构造即可。

public 类名([参数列表]){}

构造方法的特点

  • 没有返回值
  • 方法名必须和类名一致
  • 默认情况下,每个类都有一个默认的无参构造方法
  • 当你显示声明了构造方法后,默认的构造方法就无效了

示例:

public class Student {// 成员变量String username; int age;// 构造方法public Student() {System.out.println("这是一个无参构造方法");}public Student(String username, int age) {this.username = username;this.age = age;System.out.println("这是一个有参构造方法");}// 成员方法public void study(String username) {System.out.println(username+"在学习");}
}

this关键字

this表示当前对象

当前对象是谁:谁调用这个方法,当前对象就是谁

this关键字说明:this是Java提供的关键字,表示当前实例化的对象本身。

使用:

  • this.属性名:来访问类中的成员变量,用来区分成员变量和局部变量(重名问题,如前面章节的有参构造方法属性赋值);

  • this.方法名(参数值...):用来访问本类的成员方法,通常直接省略;

  • this(参数值...):访问本类的构造方法。

注意:

1、this.属性名在同一个类的方法中,用来区分成员变量和局部变量用的比较常见,且不可以省略;
​
2、this.方法名(参数值...)这种用法的this可以省略,实际上通常都会省略;
​
3、this(参数值...)调用构造方法时,必须在构造方法内的第一条执行;多个构造方法内不要相互使用来调用。

 实例:

1、this.属性名

public class Student {// 成员变量String username; int age;// 构造方法public Student() {System.out.println("这是一个无参构造方法");}public Student(String username, int age) {this.username = username;this.age = age;System.out.println("这是一个有参构造方法");}// 成员方法public void study(String username) {System.out.println(username+"在学习");}
}

2、this.方法名(参数值...)

public class ThisDemo {public void method1() {System.out.println("方法1执行");this.method2();}public void method2() {System.out.println("方法2执行");}
}
// 测试类
public class ThisTest {public static void main(String[] args) {ThisDemo t= new ThisDemo();t.method1();}
}

3、this(参数值...)

public class Student {// 成员变量String username; int age;// 构造方法public Student() {this("陈圆圆", 18); // 使用this(参数值)调用有参构造方法System.out.println("这是一个无参构造方法");}public Student(String username, int age) {this.username = username;this.age = age;System.out.println("这是一个有参构造方法");}// 成员方法public void study(String username) {System.out.println(username+"在学习");}
}
// 测试类
public class ThisTest {public static void main(String[] args) {Student s= new Student();System.out.println(s.username);System.out.println(s.age);}
}

static关键字

static关键字介绍

static关键字说明:static关键字是Java提供的,方便在没有创建对象的情况下进行调用(方法/变量)。static可以用来修饰类的成员方法、类的成员变量,另外也可以编写static代码块来优化程序性能。

使用:

  • static 成员变量:static变量也称为静态变量。表示该变量属于类

    • 静态变量被所有对象共享,在内存中只有一个副本,在类初次加载的时候才会初始化;

    • 非静态变量是对象所拥有的,在创建对象的时候被初始化,存在多个副本,各个对象拥有的副本互不影响;

    • 语法:

      static 数据类型 变量名;

      static成员变量初始化顺序按照定义的顺序来进行初始化。

  • static 方法:static方法也成为静态方法,主要用作一些工具类方法。表示该方法属于类

    • 由于静态方法不依赖于任何对象就可以直接访问,因此对于静态方法来说,是没有this的;

    • 静态方法中不能访问类的非静态成员,因为非静态成员变量和非静态方法都必须依赖于具体的对象才能被调用;

    • static方法通常作用一个工具类中统一对外提供的方法使用,比如之前学习的Arrays数组工具类中的方法都是static的。

    • 语法:

      static 返回值类型 方法名(参数列表){}

      虽然在静态方法中不能访问非静态成员方法和非静态成员变量,但是在非静态成员方法中是可以访问静态成员方法和静态成员变量。

  • static代码块:静态初始化块,用于类的初始化操作。表示是静态代码块。

    • static代码块随着类的加载而加载,并且只初始化执行一次;

    • 静态初始化块中不能直接访问非static成员;

    • 静态初始化块可以置于类中的任何地方,类中可以有多个静态初始化块,多个静态代码块会按照书写顺序加载。

    • 语法:

      static { 初始化语句 }

单例模式

单例模式(Singleton Pattern)是 Java 中最简单的设计模式之一。这种类型的设计模式属于创建型模式,它提供了一种创建对象的最佳方式。

这种模式涉及到一个单一的类,该类负责创建自己的对象,同时确保只有单个对象被创建。这个类提供了一种访问其唯一的对象的方式,可以直接访问,不需要实例化该类的对象。

注意:

  • 1、单例类只能有一个实例。

  • 2、单例类必须自己创建自己的唯一实例。

  • 3、单例类必须给所有其他对象提供这一实例。

关键代码:构造函数是私有的private。

  • 构造方法私有化
  • 提供一个公共的静态的入口方法
  • 提供一个私有的静态的成员变量

实例:

1、懒汉式,线程不安全

public class Singleton {  private static Singleton instance;  private Singleton (){}  public static Singleton getInstance() {  if (instance == null) {  instance = new Singleton();  // 创建对象是要消耗时间的  10s}  return instance;  }
}

2.饿汉式

public class Singleton {  private static Singleton instance = new Singleton();  private Singleton (){}  public static Singleton getInstance() {  return instance;  }
}

代码块

所有的代码块都不需要主动调用。

  • 局部代码块

局部代码块是写在方法中的:可以加速局部变量的生命周期,节省内存空间

  • 构造代码块

构造代码块的作用是用于创建对象之前做一些初始化动作。构造代码块在每次new对象时被JVM主动调用,且在构造方法调用前执行。

  • 静态代码块(较常用)

静态代码块的作用是用于类加载之后做一些初始化动作。静态代码块在每次类加载后被JVM主动调用,执行顺序在main方法之前。

  • 构造方法

  基本概念:用于对类进行初始化,创建对象。

  特点:每次创建对象,都会执行一遍。

 代码块对比示例

class CodeBlock {//静态代码块:类中方法外,加static修饰,用于给类进行初始化static{System.out.println("静态代码块");}//构造代码块:类中方法外,用{}括起,每次调用构造方法前执行,用于给对象进行初始化{System.out.println("构造代码块");}// 构造方法public CodeBlock(){System.out.println("无参构造");}
}public class CodeBlockDemo {public static void main(String[] args) {{System.out.println("局部代码块");}CodeBlock t2 = new CodeBlock();CodeBlock t3 = new CodeBlock();}
}

结果:

Java面对对象(基础)相关推荐

  1. java俄罗斯方块视频_[VIP视频]【A0233】java面对对象编程-俄罗斯方块视频教程 高清视频 百度云 百度网...

    Java视频教程名称:java面对对象编程-俄罗斯方块视频教程  俄罗斯方块视频教程 $ X0 X1 Z: W4 P3 T  e. m3 q百度网盘下载链接: . M% x- I- V5 p( J 游 ...

  2. Python - 面对对象(基础)

    目录 Python - 面对对象(基础) 一. 概述 二. 创建类和对象 三. 面向对象三大特征 封装 继承 多态 Python - 面对对象(基础) 一. 概述 面向过程:根据业务逻辑从上到下写垒代 ...

  3. Java基于对象基础 基于对象和面向对象的区别(转)

    Java基于对象基础 基于对象和面向对象的区别 JavaScript设计者想把javascript语言设计成基于对象(object-based)的语言,他想把这个与面向对象(object-orient ...

  4. Java面对对象(多态)

    Java面对对象(多态) 一,object类和toString Object 类|老祖宗类 ​ 是java 中所有类的父类 ​ 在java中的所有类都会直接或者间接的继承自Object类 ​ ​ to ...

  5. java面对对象编程

    因为这直接关系到你阅读设计模式的速度和理解质量. 接下来我将简单介绍java中面对对象编程的一些基础知识. 1,类和修饰符 public class ClassTest{public ClassTes ...

  6. java面对对象 关键字this super

    this:this是指向对象本身的一个指针,成员函数内部指向当前类的对象 其实this主要要三种用法: 1.表示对当前对象的引用! 2.表示用类的成员变量,而非函数参数,注意在函数参数和成员变量同名是 ...

  7. 基于java面对对象编程范式笔记

    https://www.icourse163.org/learn/NJU-1002246017?tid=1002791118#/learn/content 科学思维&工程思维 科学思维:限制条 ...

  8. Java面对对象概念,什么是面向对象

    我们都知道Java是一门面向对象的语言.什么是面向对象,它有什么特性呢,今天我们就来说一下这个"面向对象"到底是什么意思. 面向对象简称 OO(Object Oriented),2 ...

  9. java面对对象教学_Java面向对象程序设计教与学

    原标题:Java面向对象程序设计教与学 面向对象程序设计(Object Oriented Programming,OOP)主要研究如何从对象的角度出发构建程序单元以及程序开发机制,主要内容包括抽象的技 ...

最新文章

  1. 二叉树的先序遍历(非递归)
  2. Spring MVC 实现原理
  3. Linux 在脚本里面启动终端并执行命令
  4. sunday java_Sunday算法:最快的字符串匹配算法
  5. CV算法助理 | 华为外包招聘
  6. lisp 提取字符串中的數字_Redis 数据结构之字符串的那些骚操作
  7. 马斯克开始行动:下调Twitter Blue订阅费 禁止广告
  8. 别在我的坟前哭 脏了我轮回的路
  9. 13个免费创建和托管网站的在线工具[图]
  10. Let’s to be a bug-free programmer
  11. 5个酷毙的Python工具
  12. 关于吐槽网播放映兔源视频无法播放的问题 及解决方案
  13. VS-c++ 项目新建文件夹
  14. Excel2016保存文件闪退(在安装了Visio后)
  15. 吴恩达-斯坦福CS229机器学习课程资料与算法的Python实现
  16. There appears to be trouble with your network connection
  17. 爱情 何为爱情(搜集)
  18. java将图片存储在数据库(mysql)
  19. js获取本月初与月底的时间、获取前一天的时间。
  20. JAVA爬虫-上海公交线路爬取

热门文章

  1. Linux批量添加10个用户stu01,stu02....stu10,并设置8位随机密码
  2. 一位上海疫情下的悲催女程序员!
  3. 迎接2016,一个程序员的总结
  4. php mysql curd_使用PHP操作SQL 完成简单的CURD操作
  5. ITE平台开发 chapter 3-database使用
  6. echarts 折线图 设置y轴最小刻度_用plotly和plt画图的基本设置(标题、坐标轴、图例、注释、图像)...
  7. 基于stm32f103c8t6与手机蓝牙控制LED
  8. 【算法】几分钟时间让你彻底学会—时间复杂度
  9. Android 如何访问网络
  10. 使用vue-quill-editor实现富文本编辑器(封装带移入提示)