1. 内部类
如何理解内部类呢?
1.1 内部类的定义及使用方法

使用:"类中类",类的嵌套。
例:
包:com.TestInnerClass
文件1: innerClass.java
package com.TestInnerClass;
public class innerClass {
private Contents c;
private Desti d;
public innerClass(){} // 一个空的初始化方法
class Contents{ // 内部类Contents
private int value;
public Contents(int value){
this.value = value;
}
public int getValue(){
return value;
}
}
class Desti{ // 内部类Desti
private String whereTo;
public Desti(String whereTo){
this.whereTo = whereTo;
}
}
}
文件2: Test.java
package com.TestInnerClass;
public class Test {
public static void main(String[] args) {
innerClass p = new innerClass();
// 内部类调用方法:
// 外部类名.内部类名 变量名 = 已经实例化的外部类.new 内部类名(参数);
innerClass.Contents c = p.new Contents(33);
innerClass.Desti d = p.new Desti("Tianjin");
}
}
1.2 如何在内部类中使用外部类成员?
这个问题值得一说。

规则如下:
- 内部类可以直接访问外部类的字段及方法
- 如果内部类有和外部类同名的字段和方法,则:
- 外部类名.this.字段及方法
例:
IC2.java
package com.TestInnerClass;
public class IC2 {
private int s = 111;
public class IIC{ // 内部类IIC
private int s = 222;
public void mb(int s){
System.out.println(s); // 形参
System.out.println(this.s); // 内部类的s
System.out.println(IC2.this.s); // 外部类的s
}
}
}
Test.java
package com.TestInnerClass;
public class Test {
public static void main(String[] args) {
IC2 run = new IC2();
IC2.IIC tst = run.new IIC();
tst.mb(2);
}
}
1.3 内部类的修饰符
内部类也可以使用修饰符如下:
static
protected
private
-
default
(默认,一般不写) final
abstract
注:外部类只能用public
及默认(default
)来修饰
例: static

根据上图的PPT,我们可知:一旦内部类用static
修饰之后便与外部类的实例无关了,可以认为成转换为实质上的外部类。
访问规则只需要记得两点:
-
static
内部类在使用时不需要预先初始化一个外部类; -
static
内部类只能访问static
字段及方法。
1.4 局部类
定义:方法中的内部类,即“方法中的类”。
可以访问外部类的成员,但不能访问内部类中的成员,除非被final
修饰。
1.5 匿名类
一次性使用的类。
例:
MetCls.java
package com.TestInnerClass;
public class MetCls {
private int sz = 5;
public Object makeTheInner(int v){
final int fl = 99;
return new Object(){
final int finalLocalVar = 100;
@Override
public String toString(){
return ("InnerSize= " + sz + " FinalLocalVar =" + finalLocalVar);
}
};
}
}
Test.java
package com.TestInnerClass;
public class Test {
public static void main(String[] args) {
MetCls ms = new MetCls();
var k = ms.makeTheInner(8);
System.out.println(k);
}
}
2. Lambda表达式
当被问及Java 8新特性时,Lambda表达式应该属于其中之一。
Lambda表达式在其他语言中(尤其是Python)也叫匿名函数,及即没有具体名称的函数,它允许快速定义单行函数。
在Java中,例如Arrays.sort()
方法中,除了数组参数,还可以传入一个方法(method)参数来指定排序方法。这个方法参数就可以快速地用lambda表达式来做。
然而,对于Java这样的完全意义上的面向对象语言(一切皆对象)要如何实现呢?
2.1 实现方法

有如下两种方法:
-
(parameters) -> {a method};
,即在小括号中写明需要的参数,在花括号中写明实现方法。参数的类型可写可不写,因为编译器可以自动推断。 -
() -> {method;}
,在无参数时可以这样写,只是单纯实现一个方法 。
例:
package com.lambda;
import java.util.*;
import javax.swing.*;
import javax.swing.Timer;
/**
* This programme demonstrates the use of lambda expressions.
* @version 1.0 2019-11-27
* @author Allen Bayern
* */
public class LambdaTestf {
public static void main(String[] args) {
String[] planets = new String[]{"Mercury", "Venus", "Earth", "Mars", "Jupyter", "Saturn", "Uranus", "Neptune"};
System.out.println(Arrays.toString(planets));
System.out.println("Sorted in dictionary order:");
Arrays.sort(planets);
System.out.println(Arrays.toString(planets));
System.out.println("Sorted by length:");
// Lambda below:
Arrays.sort(planets, (first, second) -> first.length() - second.length());
System.out.println(Arrays.toString(planets));
Timer timer = new Timer(1000, (event) -> System.out.println("The time is" + new Date()));
timer.start();
// keep programme running until user selects "OK".
JOptionPane.showMessageDialog( null, "Quit Programme?" );
System.exit(0);
}
}
2.2 函数式接口
那么什么样的方法可以被写成Lambda表达式呢?通常只有一个抽象方法的接口更易实现为Lambda表达式。

从上图可看出,Lambda函数的实质是接口函数的简写,即不单独占用一行来实现接口,而是放到传参里直接实现。

能写成Lambda函数的接口只能有一个,且至多一个抽象方法。最好在前面加上@FunctionalInterface
注解。例如:
@FunctionalInterface
interface Fun{ double fun(double x); }
2.3 举例:Comparator接口
这是一个系统自带的单方法接口,所以可以写成Lambda表达式。上例代码中就用到了该接口。
源码如下:
public interface Comparator<T>{
int copare(T first, T second);
}
回到上面的代码,我们发现了这么一行:
Arrays.sort(planets, (first, second) -> first.length() - second.length());
如果不用Lambda表达式的话,我们要这样写:
// 下面的代码与上面的Lambda形式等效
class LenComparator implements Comparator<String>{
public int compare(String first, String second){
return (first.length() - second.length());
}
}
Arrays.sort(planets, new LenComparator());
这样一看,是不是Lambda简洁了许多?
网友评论