# 内部类
# 基本概念
内部类是指在类内部定义的普通类,抽象类,接口的统称,在一个类的内部出了属性和方法还能定义类,这使程序的结构定义更加灵活。
class OuterClass{
private String info="This is outer info!";
public void GenInner() {
InnerClass innerObj = new InnerClass();
innerObj.GetInnerInfo();
}
class InnerClass{
public void GetInnerInfo() {
System.out.println(OuterClass.this.info);
}
}
}
public class Main {
public static void main(String[] args){
OuterClass outObj = new OuterClass();
outObj.GenInner();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
注意:
- 内部类能比较方便地访问外部类的私有成员,外部类也能比较方便地访问内部类的私有成员。
- 内部类可以被单独地实例化,但是需要先实例化外部类。如果不希望在外部实例化内部类,需要在内部类前使用private修饰。
# 接口内部类
内部类可以在接口里面定义:
interface IOuterInterface{
public void getOuterInfo();
interface IInnerInfo{
public void getInnerInfo();
}
}
class OuterImpl implements IOuterInterface{
@Override
public void getOuterInfo() {
// TODO Auto-generated method stub
System.out.println("Output outer class info!");
InnerImpl innerObj = new InnerImpl();
innerObj.getInnerInfo();
}
class InnerImpl implements IInnerInfo{
@Override
public void getInnerInfo() {
// TODO Auto-generated method stub
System.out.println("Output inner class info!");
}
}
}
public class Main {
public static void main(String[] args){
OuterImpl o1 = new OuterImpl();
o1.getOuterInfo();
}
}
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
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
在接口中定义抽象类:
interface IOuterInterface{
public void getOuterInfo();
abstract class InnerAbstractClass{
public abstract void GetInnerInfo();
}
}
class OuterImpl implements IOuterInterface{
@Override
public void getOuterInfo() {
// TODO Auto-generated method stub
System.out.println("Output outer class info!");
innerClass innerClassObj = new innerClass();
innerClassObj.GetInnerInfo();
}
class innerClass extends InnerAbstractClass{
@Override
public void GetInnerInfo() {
// TODO Auto-generated method stub
System.out.println("abstract class info!");
}
}
}
public class Main {
public static void main(String[] args){
OuterImpl o1 = new OuterImpl();
o1.getOuterInfo();
}
}
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
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
接口子类定义实现自身接口的类,在JDK1.8以后在接口中可定义static方法,可利用内部类的概念直接在接口中进行该接口子类的定义。
interface IOuterInterface{
public void getOuterInfo();
class OuterClass implements IOuterInterface{
@Override
public void getOuterInfo() {
// TODO Auto-generated method stub
System.out.print("Outer class implements IOuterInterface!");
}
}
public static IOuterInterface getInstance(){
return new OuterClass();
}
}
public class Main {
public static void main(String[] args){
IOuterInterface outerInterface = IOuterInterface.getInstance();
outerInterface.getOuterInfo();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# 内部静态类
使用static定义内部类时,此时的内部类不再受外部类实例化对象的影响,等同于是一个外部类。
interface MyInterface{
static interface Common {
void getInfo(String targetStr);
}
}
class MyInterfaceImpl implements MyInterface.Common{
@Override
public void getInfo(String targetStr) {
// TODO Auto-generated method stub
System.out.println("Common interface:"+targetStr);
}
}
class OuterClass{
private static final String info ="outer class info!";
static class Inner{
public void printInfo(MyInterface.Common interface1) {
interface1.getInfo(info);
}
}
}
public class Main {
public static void main(String[] args){
OuterClass.Inner o1 = new OuterClass.Inner();
MyInterfaceImpl m1= new MyInterfaceImpl();
o1.printInfo(m1);
}
}
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
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
# 方法中的内部类
内部类可在任何代码块或方法中定义,在JDK1.8之前,内部类要访问方法的参数,需要添加final关键字,就像testScope2一样。
public class Main {
public static void main(String[] args){
testScope("hello world!");
testScope2("hi world!");
}
public static void testScope(String str) {
class Inner{
public void PrintInner() {
System.out.println(str);
}
}
Inner innerObj1 = new Inner();
innerObj1.PrintInner();
}
public static void testScope2(final String str) {
class Inner{
public void PrintInner() {
System.out.println(str);
}
}
Inner innerObj1 = new Inner();
innerObj1.PrintInner();
}
}
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
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
# 匿名内部类
在一个接口或抽象类完成后,当我们需要一个子类时我会先定义一个子类然后使用,如果这个子类可能只用一次,为它单独创建一个类文件很不合理,这个时候就用匿名类了:
interface ITempInterface{
public void send(String str);
}
class TempClass{
public void Send(String str) {
System.out.println("this is org string:"+str);
}
}
public class Main {
public static void main(String[] args){
ITempInterface t1 = new ITempInterface() {
@Override
public void send(String str) {
// TODO Auto-generated method stub
System.out.println(str);
}
};
t1.send("hello world!");
TempClass tempClassObj1 = new TempClass() {
@Override
public void Send(String str) {
System.out.println("this is new string:"+str);
}
};
tempClassObj1.Send("xie");
}
}
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
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
在接口中可使用匿名类来实现接口:
interface InfoMessage{
public void send(String str);
public static InfoMessage getInstance() {
return new InfoMessage() {
@Override
public void send(String str) {
// TODO Auto-generated method stub
System.out.println("infoMessage:"+str);
}
};
}
}
public class Main {
public static void main(String[] args){
InfoMessage infomessage1 = InfoMessage.getInstance();
infomessage1.send("useful info!");
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# Lambda表达式
Lambda表达式是从JDK1.8中引入的,是指应用在SAM(Simple Abstract Method,含有一个抽象方法的接口)下的一种简化形式,用来解决匿名内部类定义的问题。
interface InfoMessage{
public void send(String str);
}
@FunctionalInterface
interface MyMath{
public int Add(int a,int b);
}
public class Main {
public static void main(String[] args){
InfoMessage infomessage1 = (str)->{
System.out.println("Lambda 方法:"+str);
};
infomessage1.send("useful info!");
MyMath mathOper = (a1,a2)->a1+a2;
System.out.println("a1+a2:"+mathOper.Add(1,20));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 方法引用
在Java中利用对象的引用可以用不同的变量来引用相同的内存空间,从JDK1.8开始,方法也支持引用操作,相当于为方法定义了别名。方法的引用有四种形式:
- 引用静态方法: 类名::方法名
- 引用对象方法: 类名::普通方法
- 引用特定类型的方法: 特定类::普通方法
- 引用构造方法: 类名::new
@FunctionalInterface
interface IFuncFromStatic<P,R>{
public R change(P p);
}
@FunctionalInterface
interface IFuncFromCommon<R>{
public R MyUpper();
}
@FunctionalInterface
interface IFuncFromClassCommon<P>{
public int compare(P p1,P p2);
}
public class Main {
public static void main(String[] args){
IFuncFromStatic<Integer,String> staticRef = String::valueOf;
String str = staticRef.change(1000);
System.out.println(str.length());
IFuncFromCommon<String> commonRef = "hello world!"::toUpperCase;
System.out.println(commonRef.MyUpper());
IFuncFromClassCommon<String> commonClassCompare = String::compareTo;
System.out.println(commonClassCompare.compare("hello", "hi"));
}
}
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
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
下面是调用构造函数:
class MyClass{
public MyClass() {
// TODO Auto-generated constructor stub
System.out.println("this is myclass constructor!");
}
}
@FunctionalInterface
interface IFuncFromNew<R>{
public R NewMyClass();
}
public class Main {
public static void main(String[] args){
IFuncFromNew<MyClass> createClass = MyClass::new;
createClass.NewMyClass();
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 内建函数式接口
函数式接口是实现Lambda表达式的关键,在上面方法的引用中发现,不管如何操作,函数式接口最多有四种:
- 有参数有返回值
- 有参数无返回值
- 无参数有返回值
- 判断真假
为了简化开发者定义,从JDK1.8之后提供了新包:java.util.function,此包中提供了很多内置的函数式接口,以上面四个核心接口为例,它们的原型为:
//功能型函数式接口
@FunctionalInterface
public interface Function<T,R>{
public R apply(T t);
}
//消费型函数式接口
@FunctionalInterface
public interface Consumer<T>{
public void accept(T t);
}
//供给型函数式接口
@FunctionalInterface
public interface Supplier<T>{
public T get();
}
//断言型函数式接口
@FunctionalInterface
public interface Predicate<T>{
public boolean(T t);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
它们的实例为:
import java.util.function.*;
public class Main {
public static void main(String[] args){
//功能型函数式接口
Function<String, Boolean> beginWith = "*Hello world!"::startsWith;
System.out.println(beginWith.apply("*"));
//消费型函数式接口
Consumer<String> MyPrint = System.out::println;
MyPrint.accept("hello");
//供给型函数式接口
Supplier<String> changeToUpper = "hello world"::toUpperCase;
System.out.println(changeToUpper.get());
//断言型函数式接口
Predicate<String> pre = "hello world"::endsWith;
System.out.println(pre.test("rld"));
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22