java学习笔记——基础12(修饰符,“变参”方法,Comparable、Comparator接口,lambda表达式)

1、不同修饰符混合使用细节
2、辨析何时定义变量为成员变量
3、类、抽象类、接口作为方法参数
4、类、抽象类、接口作为方法返回值
5、参数数量可变的方法(“变参”方法)
6、Comparable 接口 && Comparator 接口
7、lambda表达式

不同修饰符使用细节

A: 常用来修饰类、方法、变量的修饰符如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
public 权限修饰符,【公共访问】, "类,方法,成员变量"
—————————————————————————————————————————————————————————
protected 权限修饰符,【受保护访问】, "方法,成员变量""注意【不能】修饰类"
—————————————————————————————————————————————————————————
 【默认什么也不写】 也是一种权限修饰符,【默认访问】, "类,方法,成员变量"
—————————————————————————————————————————————————————————
private 权限修饰符,【私有访问】, "方法,成员变量"
————————————————————————————————————————————————————————————————————————————————————————
static 静态修饰符 "方法,成员变量,静态内部类"
—————————————————————————————————————————————————————————
final 最终修饰符 "类,方法,成员变量,局部变量"
—————————————————————————————————————————————————————————
abstract 抽象修饰符 "类 ,方法"

B: 不能同时使用的修饰符

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
同时,abstractprivate "不能"同时使用;(私有abstract不能继承,无意义)
同时,abstractstatic "不能"同时使用;(abstract没有方法体,静态通过类名调用,无意义)
同时,abstractfinal "不能"同时使用。(abstract没有方法体,final不能重写,无意义)
————————————————————————————————————————————————————————————————————————————————————————

小结:
1.抽象方法只能定义在抽象类中,抽象方法和抽象类必须由abstract修饰,abstract关键字只能描述类和方法,不能描述变量。
抽象方法只定义方法声明,不定义方法实现。抽象类不可以被实例化(创建对象),
只有通过子类继承抽象类并覆盖抽象类中的所有抽象方法后,该子类才可以被实例化,否则该子类还是一个抽象类。
抽象类中有构造函数用于给子类对象进行初始化,同时"抽象类中【可以】含有非抽象方法"
—————————————————————————————————————————————————————————
abstract关键字"不可以"finalprivate,static关键字共存,因为被final修饰的方法不可以被重写,
意味着子类不可以重写该方法,如果abstractfinal共同修饰父类中的方法,子类要实现抽象方法(abstract的作用),
final又不让该方法重写,这相互矛盾。如果privateabstract共同修饰父类中的方法,private修饰则该方法不可以被子类访问,
但是abstract修饰需要子类去实现,两者产生矛盾。如果staticabstract共同修饰父类中的方法,
static表示是"静态的方法,随着类的加载而加载,则该方法不需要在子类中去实现",这与abstract关键字矛盾。
————————————————————————————————————————————————————————————————————————————————————————
2.static用于修饰成员变量和成员函数,想要"实现对象中的【共性数据】的【对象共享】",可以将这个数据进行静态修饰,
"被静态修饰的成员可以直接被类名调用,静态随着类的加载而加载,而且优先于对象存在"
"静态方法只能访问静态成员(静态方法和静态变量),不可以【直接】用【成员名】访问非静态成员,需要new(创建对象)访问。
这是因为静态方法加载时,优先于对象存在,所以没有办法访问对象中的成员"
静态方法中"不能"使用thissuper关键字,
因为this代表本类对象,super代表父类对象,而静态时,有可能没有对象存在,所以thissuper无法使用。
————————————————————————————————————————————————————————————————————————————————————————
3.final关键字可以修饰类,方法,变量(成员变量内,局部变量,静态变量),
final修饰的类是一个最终类,不可以被继承,
final修饰的方法是一个最终方法,不可以被覆盖,但是可以被继承。
final修饰的变量只能是一个常量,只能赋值一次。内部类被定义在类中的局部位置上时,只能访问局部被final修饰的局部变量。

 C: 修饰能够使用的修饰符:

1
2
3
4
5
6
7
8
9
修饰类【只能】使用public、默认的、finalabstract关键字
静态内部类:static
使用最多的是 public关键字

a:代码案例
public class Demo {} //最常用的方式
class Demo2{}
public final class Demo3{}
public abstract class Demo4{}

D:修饰成员变量能够使用的修饰符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
public : 公共的
protected : 受保护的
: 默认的
private :私有的

"【权限修饰符都可以】"
————————————————————————————————————————————————————————————————————————————————————————
final : 最终的
static : 静态的
使用最多的是 private

修饰【成员变量】,【除了】 abstract 都可以
————————————————————————————————————————————————————————————————————————————————————————
a: 代码案例
public int count = 100;
protected int count2 = 100;
int count3 = 100;
private int count4 = 100; //最常用的方式
public final int count5 = 100;
public static int count6 = 100;

 E:修饰构造方法能够使用的修饰符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
public : 公共的
protected : 受保护的
: 默认的
private :私有的

"【权限修饰符都可以】"
————————————————————————————————————————————————————————————————————————————————————————
使用最多的是 public

a:代码案例
public Demo(){} //最常用的方式
protected Demo(){}
Demo(){}
private Demo(){}

 F:修饰成员方法能够使用的修饰符:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
public : 公共的
protected : 受保护的
: 默认的
private :私有的

"【权限修饰符都可以】"
————————————————————————————————————————————————————————————————————————————————————————

final : 最终的
static : 静态的
abstract : 抽象的

————————————————————————————————————————————————————————————————————————————————————————

使用最多的是 public

a:代码案例
public void method1(){}//最常用的方式
protected void method2(){}
void method3(){}
private void method4(){}
public final void method5(){}
public static void method6(){}//最常用的方式
public abstract void method7();//最常用的方式

局部变量和成员变量解析

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
50
51
52
53
 定义长方形类,包含求周长与求面积的方法
 定义数学工具类,包含求两个数和的二倍与求两个数积的方法
【思考】:这两个类的计算方法均需要两个数参与计算,请问两个数定义在【成员位置】还是【形参位置】更好,为什么?
"如果变量是【该类的一部分】时,定义成【成员变量】。 "
"如果变量【不应该是类的一部分】,而仅仅是【功能】当中需要【参与计算的数】,则定义为【形参变量】。"

* A:程序编译

 数学工具类
public class MathTool {
//求两个数的和的二倍
public double sum2times(int number,int number2) {
return (number+number2)*2;
}
//求两个数的积
public double area(int number,int number2) {
return number*number2;
}
}

 长方形类

public class CFX {
//因为长与宽,在现实事物中属于事物的一部分,所以定义成员变量
private int chang;
private int kuan;

public CFX(int chang, int kuan) {
this.chang = chang;
this.kuan = kuan;
}

//求长与宽的周长
public double zhouChang() {
return (chang+kuan)*2;
}
//求长与宽的面积
public double mianJi() {
return chang*kuan;
}
public int getChang() {
return chang;
}
public void setChang(int chang) {
this.chang = chang;
}
public int getKuan() {
return kuan;
}
public void setKuan(int kuan) {
this.kuan = kuan;
}
}

类作为方法的参数与返回值

* A: 类作为方法参数
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
在编写程序中,会经常碰到调用的方法要接收的是一个类类型的情况,那么这时,要向方法中传入该类的对象。

如下代码演示:
class Person{
public void show(){
System.out.println("show方法执行了");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//创建Person对象
Person p = new Person();
//调用method方法
method(p);
}

//定义一个方法method,用来接收一个Person对象,在方法中调用Person对象的show方法
public static void method(Person p){
p.show();
}

————————————————————————————————————————————————————————————————————————————————————————
 B:类作为方法返回值
写程序调用方法时,我们以后会经常碰到"【返回】一个【类】类型的【返回值】"
那么这时,该方法要"返回"return)一个"【该类的对象】"。如下代码演示:
class Person{
public void show(){
System.out.println("show方法执行了");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//调用method方法,获取返回的Person对象
Person p = method();
//调用p对象中的show方法
p.show();
}

//定义一个方法method,用来获取一个Person对象,在方法中完成Person对象的创建
public static Person method(){
Person p = new Person();
//返回的是 【类的对象】
return p;
}
}

抽象类作为方法参数与返回值

* A: 抽象类作为方法参数
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
今后开发中,【抽象类】作为【方法参数】的情况也很多见。
"当遇到【方法参数】为【抽象类】类型时,要传入一个【实现】【抽象类】【所有抽象方法】的【子类对象】"
"抽象类【没有对象】,只能通过【多态】的方式,传递【抽象类】的【子类】的【对象】"

如下代码演示:

//抽象类
abstract class Person{
public abstract void show();
}
class Student extends Person{
@Override
public void show() {
System.out.println("重写了show方法");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//通过多态的方式,创建一个Person类型的变量,而这个对象实际是Student
Person p = new Student();
//调用method方法
method(p);
}

//定义一个方法method,用来接收一个Person类型对象,在方法中调用Person对象的show方法
public static void method(Person p){//抽象类作为参数
//抽象类【没有对象】,只能通过【多态】的方式,传递【抽象类】的【子类】的【对象】
//通过p变量调用show方法,这时实际调用的是Student对象中的show方法

p.show();
}
}

————————————————————————————————————————————————————————————————————————————————————————
* B: 抽象类作为方法返回值
"【抽象类】作为【方法返回值】的情况,这时需要【返回】一个实现抽象类【所有抽象方法】的【子类对象】。"
"抽象类【没有对象】,只能通过【多态】的方式,返回的是【抽象类】的【子类】的【对象】"

如下代码演示:

//抽象类
abstract class Person{
public abstract void show();
}
class Student extends Person{
@Override
public void show() {
System.out.println("重写了show方法");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//调用method方法,获取返回的Person对象
Person p = method();
//通过p变量调用show方法,这时实际调用的是Student对象中的show方法
p.show();
}

//定义一个方法method,用来获取一个Person对象,在方法中完成Person对象的创建
public static Person method(){
Person p = new Student();
//抽象类【没有对象】,只能通过【多态】的方式,返回的是【抽象类】的【子类】的【对象】
return p;
}
}

接口作为方法参数与返回值

* A: 接口作为方法参数
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
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
【接口】作为【方法参数】的情况是很常见的,经常会碰到。
当遇到方法参数为【接口类型】时,那么该方法要传入一个"【接口实现类】【对象】"

"【接口】【没有对象】,只能通过【多态】的方式,【传入】的是【接口】的【实现类】的【对象】"
如下代码演示。
//接口
interface Smoke{
public abstract void smoking();
}
class Student implements Smoke{
@Override
public void smoking() {
System.out.println("no smoking");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//通过多态的方式,创建一个Smoke类型的变量,而这个对象实际是Student
Smoke s = new Student();
//调用method方法
method(s);
}

//定义一个方法method,用来接收一个Smoke类型对象,在方法中调用Smoke对象的show方法
public static void method(Smoke sm){//接口作为参数
//通过sm变量调用smoking方法,这时实际调用的是Student对象中的smoking方法
sm.smoking();
}
}

————————————————————————————————————————————————————————————————————————————————————————

* B: 接口作为方法返回值
接口作为方法返回值的情况,在后面的学习中会碰到。
当遇到方法返回值是接口类型时,那么该方法需要返回一个"【接口实现类对象】"
"【接口】【没有对象】,只能通过【多态】的方式,【返回】的是【接口】的【实现类】的【对象】"

如下代码演示。

//接口
interface Smoke{
public abstract void smoking();
}
class Student implements Smoke{
@Override
public void smoking() {
System.out.println("no smoking");
}
}
//测试类
public class Test {
public static void main(String[] args) {
//调用method方法,获取返回的会吸烟的对象
Smoke s = method();
//通过s变量调用smoking方法,这时实际调用的是Student对象中的smoking方法
s.smoking();
}

//定义一个方法method,用来获取一个具备吸烟功能的对象,并在方法中完成吸烟者的创建
public static Smoke method(){
Smoke sm = new Student();
return sm;
}
}

星级酒店案例

* A:     根据“某五星级酒店,资金雄厚……都有自己的工作要做。”分析出,该题        
    目中包含酒店,可以把它封装成类,多名员工)。
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
class 员工 {
属性:姓名
属性:工号
方法:工作
}
class 厨师 extends 员工{}
class 服务员 extends 员工{}
class 经理 extends 员工 {
属性:奖金
}

员工的类型有经理、厨师、服务员,它们有共同的属性(姓名、工号、),经理额外属性(奖金)。

 根据“向酒店中,增加多名员工(其中包含1名经理,1名厨师、2名服务员)”。分析出,要创建一个酒店对象,并添加4名员工到酒店对象的员工集合中。
酒店员工集合添加新员工: 经理对象
酒店员工集合添加新员工: 厨师对象
酒店员工集合添加新员工: 服务员对象
酒店员工集合添加新员工: 服务员对象

 根据“获取酒店幸运员工”。分析出,从酒店员工集合随机得到一名员工对象。
1. 从酒店员工集合长度范围内,随机产生一个随机数
2. 使用该随机数作为集合的索引,返回该索引处对应的员工对象

 根据“酒店开设VIP服务,酒店的厨师与服务员可以提供VIP服务。(厨师做菜加量、服务员给顾客倒酒)”。分析出,这是要增加一个VIP的接口,接口中提供个VIP服务的方法。让厨师与服务员实现该接口。
interface VIP服务{
抽象方法:服务
}
class 厨师 extends 员工 implements VIP服务{ 重写服务方法 }
class 服务员 extends 员工 implements VIP服务{ 重写服务方法 }
B:
    VIP服务
public interface VIP {
 public abstract void server(); //服务
}

 员工

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
/*
* 员工:
姓名 String
工号 String

*/
public abstract class YuanGong {
// 成员变量
private String xingMing;
private String gongHao;
// 构造方法
public YuanGong() {
super();
}
public YuanGong(String xingMing, String gongHao) {
super();
this.xingMing = xingMing;
this.gongHao = gongHao;

}
// 抽象方法
public abstract void work();

// getters与setters
public String getXingMing() {
return xingMing;
}
public void setXingMing(String xingMing) {
this.xingMing = xingMing;
}
public String getGongHao() {
return gongHao;
}
public void setGongHao(String gongHao) {
this.gongHao = gongHao;
}

}

 服务员

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* 定义员工的子类 服务员类
*/
public class FuWuYuan extends YuanGong implements VIP {
public FuWuYuan() {
super();
}

public FuWuYuan(String xingMing, String gongHao) {
super(xingMing, gongHao);
}
@Override
public void work() {
System.out.println("亲,全身心为您服务,记得给好评哦");
}
@Override
public void server() {
System.out.println("给顾客倒酒");
}
}

 经理

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
/*
* 经理在员工的基础上,添加了奖金成员
*/
public class JingLi extends YuanGong {
private double jiangJin;

public JingLi() {
super();
}
public JingLi(String xingMing, String gongHao, double jiangJin) {
super(xingMing, gongHao);
this.jiangJin = jiangJin;
}

public double getJiangJin() {
return jiangJin;
}
public void setJiangJin(double jiangJin) {
this.jiangJin = jiangJin;
}

@Override
public void work() {
System.out.println("哪个员工让顾客不满意,我扣谁钱");
};
}

 厨师

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
/*
* 定义员工的子类 厨师类
*/
public class ChuShi extends YuanGong implements VIP{
public ChuShi() {
super();
}
public ChuShi(String xingMing, String gongHao) {
super(xingMing, gongHao);
}

@Override
public void work() {
System.out.println("我做饭,放心吃吧,包您满意");
}
@Override
public void server() {
System.out.println("做菜加量加料");
}
}

参数数量可变的方法(“变参”方法)

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
现在的版本提供了可以用可变的参数数量调用的方法(有时称为“ 变参” 方法。)
printf方法是这样定义的:
public class PrintStream
{
public PrintStream printf(String fmt , Object ... args) {
return format(fmt, args);
}
}
这里的省略号 . . . 是 Java 代码的一部分,它表明这个方法可以接收任意数量的对象(除 format参数之外。)
———————————————————————————————————————————————————————————————————————————————————————————
实际上,printf 方法接收"两个参数", 一个是"格式字符串", 另一个是 "Object [] 数组"
"Object [] 数组" 保存着所有的参数
"如果调用者提供的是【整型数组或者其他基本类型】的值, 【自动装箱】功能将【把它们】【转换成对象】 )。
现在将扫描format 字符串, 并将第 i 个格式说明符与 args[i] 的值匹配起来"
=>> "Object… 参数类型与 Object[ ] 完全一样"
———————————————————————————————————————————————————————————————————————————————————————————
编译器需要对 printf 的每次调用进行转换, 以便将参数绑定到数组上, 并在必要的时候
进行自动装箱:
System.out.printf("%d %s", new Object [] { new Integer(n), "widgets" } );
"用户自己也可以定义可变参数的方法, 并将参数指定为【任意类型】, 【甚至】是【基本类型】"
———————————————————————————————————————————————————————————————————————————————————————————

public class Demo {
public static void main(String[] args) {
func("How ","are ","you");
}
public static void func(String ... args){//等效于 args -> new String []{"How ","are ","you"};
for(String value : args){
System.out.println(value);
}
}
}
编译器将 new String []{"How ","are ","you"} 传递给 args
甚至可以将 main 方法声明为下列形式:
public static void main(String... args)

Comparable 接口 && Comparator 接口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15


### 总结
``` java
不同修饰符的使用
类,最常使用public修饰
成员变量,最常使用private修饰
成员方法,最常使用public修饰
自定义数据类型的使用
"【类】作为【方法参数】时,说明要向方法中传入【该类的对象】"
"【类】作为【方法返回值】时,说明该方法要返回一个【该类的对象】。"
"【抽象类】作为【方法参数】时,说明要传入一个实现【抽象类】【所有抽象方法】的【子类对象】。"
"【抽象类】作为【方法返回值】时,说明需要返回一个实现【抽象类】【所有抽象方法】的【子类对象】。"
"【接口】作为【方法参数】时,说明该方法要传入一个【接口】【实现类对象】。"
"【接口】作为【方法返回值】时,说明该方法需要返回一个【接口】【实现类对象】。"
-------------本文结束感谢您的阅读-------------
感谢您的支持,我会继续努力的!
0%