方法的递归调用

  • 基本概念

    递归主要指在方法体内部调用当前方法自身的形式。

  • 使用原则

1
2
3
(1)使用递归必须找到规律和退出条件;
(2)使用递归必须使得问题简单化而不是复杂化;
(3)若递归影响程序的执行性能,使用递推取代之;
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
/*
编程实现阶乘的计算并打印
*/
public class JieChengTest {
// 自定义成员方法计算参数n的阶乘并返回 n = 5; 递推
int show(int n) { //int n=5; int n=4; int n=3; int n=2; int n=1;

// 递推的方式计算阶乘
/*
int num = 1;
for(int i = n; i > 1; i--) {
num *= i; // num = num*i = 5; num = 20; num = 60; num = 120;
}
return num;
*/

// 递归的方式计算阶乘
if(1 == n) {
return 1;
}
return n * show(n-1);
// show(5) = 5 * show(4); = 120
// show(4) = 4 * show(3); = 24
// show(3) = 3 * show(2); = 6
// show(2) = 2 * show(1); = 2
// show(1) = 1;
}

public static void main(String[] args) {
JieChengTest jct = new JieChengTest();
int res = jct.show(5);
System.out.println("最终的计算结果是:" + res); // 120
}
}

封装(重中之重)

  • 基本概念

    通常情况下可以给成员变量赋值合法但不合理的数值,此时无论是编译阶段还是运行阶段都不会报错或给出提示,因此与现实生活不符。

    为了避免上述错误的发生,就需要对成员变量进行密封包装处理,这种处理机制就叫做封装,换句话说,封装就是一种保证成员变量值合理和隐藏的机制。

  • 实现流程

    (1)私有化成员变量,使用private关键字修饰;

    (2)提供公有的get和set方法,在方法体中进行合理值的判断;

    (3)在构造方法中调用set方法进行合理值的判断;

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
/*
编程实现Person类的封装
*/
public class Person {
// 1.私有化成员变量,使用private关键字修饰
private String name;
private int age;
// 提升为类层级,被所有对象共享,使用类名.的方式访问
//private String country;
public static String country;

// 3.在构造方法中调用set方法进行合理值的判断
public Person() {
}
public Person(String name, int age, String country) {
setName(name);
setAge(age);
setCountry(country);
}

// 2.提供公有的get和set方法,并在方法体中进行合理值的判断
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
if(age > 0 && age < 150) {
this.age = age;
} else {
System.out.println("年龄不合理!!!");
}
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}

// 自定义成员方法实现所有特征的打印
public void show() {
System.out.println("我是" + getName() + ",今年" + getAge() + "岁了,来自" + getCountry());
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
/*
编程实现Person类的测试
*/
public class PersonTest {

public static void main(String[] args) {
// 测试一下static修饰的成员变量是否可以在不创建对象时也能访问
System.out.println("获取到的国籍是:" + Person.country); // null

// 使用有参方式构造两个对象并打印特征
Person p1 = new Person("zhangfei", 30, "China");
p1.show(); // zhangfei 30 China

Person p2 = new Person("guanyu", 35, "China");
p2.show(); // guanyu 35 China

System.out.println("-----------------------------------");
// 测试一下static修饰的成员变量是否被所有对象共享
p1.country = "蜀国";
System.out.println("修改后的国籍是:" + p1.country); // 蜀国
System.out.println("p2.country = " + p2.country); // 蜀国

Person p3 = new Person();
p3.setName("liubei");
System.out.println("p3.country = " + p3.country); // 蜀国
}
}

static关键字

  • 基本概念

    通常情况下成员变量隶属于对象层级,创建一个新的对象后就会申请独立的存储空间存放该对象独有的成员变量信息,若所有对象中某个成员变量的数值一定相同时还要在每个对象中单独存储,此时会造成内存空间的浪费。

    为了解决上述问题,在Java语言中使用static关键字修饰成员变量表示静态的含义,此时成员变量由对象层级提升到类层级被所有对象共享,该成员变量随着类的加载准备就绪与是否创建对象无关。

    static关键字还可以修饰成员方法,虽然可以使用引用.访问,但推荐使用类名.访问

  • 使用方式

1
2
3
4
5
6
(1)非静态成员方法中既能访问非静态的成员也能访问静态的成员;
(成员:成员变量 + 成员方法, 静态成员被所有对象共享)
(2)静态成员方法中只能访问静态的成员不能访问非静态的成员;
(成员:成员变量 + 成员方法, 非静态成员隶属于对象层级,此时可能没有对象)
(3)只有隶属于类层级被所有对象共享的内容才可以使用static关键字修饰;
(不能滥用static关键字)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
/*
编程实现static关键字的使用
*/
public class StaticTest {

private int cnt = 1; // 隶属于对象层级,每个对象都拥有独立的一份
private static int snt = 2; // 隶属于类层级,所有对象共享同一份

// 隶属于对象层级
public void show() {
System.out.println("cnt = " + this.cnt); // ok 1
System.out.println("snt = " + this.snt); // ok 2
}

// 隶属于类层级
public static void test() {
//System.out.println("cnt = " + cnt); // error
System.out.println("snt = " + snt); // ok 2
}

public static void main(String[] args) {
StaticTest.test();
StaticTest st = new StaticTest();
st.show();
}
}

单例设计模式(重中之重)

  • 基本概念

    在某些特殊场合中,一个类对外提供且只提供一个对象,这样的类叫做单例类。而设计单例类的思想和模式叫做单例设计模式。

  • 实现流程

    a.私有化构造方法,使用private关键字修饰;

    b.声明本类类型的引用指向本类的对象,并使用private static关键字共同修饰;

    c.提供公有的get方法负责将对象返回出去,并使用static关键字修饰;

  • 实现方式

    单例设计模式的实现方式有两种:饿汉式 和懒汉式,以后开发中推荐饿汉式。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
  /*
编程实现Singleton类的封装
*/
public class Singleton {

// 2.提供本类类型的引用指向本类类型的对象
// 数据类型 成员变量名 = 初始值;
//private static Singleton sin = new Singleton(); // 饿汉式
private static Singleton sin = null; // 懒汉式

// 1.私有化构造方法,使用private关键字修饰
// private关键字修饰的内容表示私有的,也就是只能在本类的内部使用
private Singleton(){}

// 3.提供公有的get方法负责将上面的对象返回出去
public static Singleton getInstance() {
//return sin;
if(null == sin) {
sin = new Singleton();
}
return sin;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
/*
编程实现Singleton类的测试
*/
public class SingletonTest {

public static void main(String[] args) {
/*
Singleton s1 = new Singleton();
Singleton s2 = new Singleton();
System.out.println(s1 == s2); // false
*/
Singleton s1 = Singleton.getInstance();
Singleton s2 = Singleton.getInstance();
System.out.println(s1 == s2); // true
}
}