内部类:
在一个类中定义一个类.
**分类:**成员内部类:在类的成员位置
局部内部类:在类的局部位置
例子:成员内部类
public class Test1Inner {
public static void main(String[] args) {
/*
创建内部类对象的格式:
外部类名.内部类名 对象名 = new 外部类对象().new 内部类对象();
*/
//访问内部类的成员
Outer.Inner i = new Outer().new Inner();
System.out.println(i.num);
i.show();
}
}
class Outer{
int a = 10;
class Inner{
//成员内部类
int num = 10;
public void show(){
System.out.println("Inner..show");
//内部类去访问外部类成员,可以直接访问,包括私有
//外部类要访问内部类成员,就必须创建对象
System.out.println(a);
}
}
}
成员内部类–
概述:
定义在类中方法之外的内部类.
私有成员内部类访问(private):在自己所在的外部类中创建对象访问.
static:
静态成员内部类访问:外部类名.内部类名 对象名 = new 外部类名.内部类名();
静态成员内部类中的静态方法:外部类名.内部类名.方法名();
public class Test2Innerclass {
/*
私有成员内部类演示
*/
public static void main(String[] args) {
//Outer.Inner oi = new Outer().new Inner();Inner被private私有化,访问不到
Outer o = new Outer();
o.method();
}
}
class Outer{
private class Inner{
public void show(){
System.out.println("inner..show");
}
}
//就在自己里面,直接访问就OK
public void method(){
Inner i = new Inner();
i.show();
}
}
public class Test3Innerclass {
/*
静态成员内部类
*/
public static void main(String[] args) {
//对于静态成员内部类
//外部类名.内部类名 对象名 = new 外部类名.内部类名();
Outer.Inner oi = new Outer.Inner();
oi.show();
Outer.Inner.method();
}
}
class Outer{
static class Inner{
public void show(){
System.out.println("inner..show");
}
public static void method(){
System.out.println("inner..method");
}
}
}
局部内部类:
局部内部类是在方法中定义的类,所以外界是无法直接使用的,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
作用:
方法内部的东西,在方法执行完毕后会自动消失.
所以,局部内部类可以用于"临时性的创建子类对象"
public class Test4InnerClass {
/* 局部内部类
编写位置:方法中
访问方式:只能在方法中,创建对象并访问
*/
public static void main(String[] args) {
Outer o = new Outer();
o.method();
}
}
class Outer{
public void method(){
class Inner{
public void show(){
System.out.println("show...");
}
}
Inner i = new Inner();
i.show();
}
}
匿名内部类:重要
本质上是一个对象
概述:匿名内部类本质上是一个特殊的局部内部类(定义在方法内部)
前提:需要存在一个接口或类
格式:
new 类名或者接口名(){
重写方法;
};
范例:
new Inter(){
public void show(){
}
}
例子:
public class Test5InnerClass {
/*
1.创建实现类,通过implements关键字去实现接口
2.重写方法
3.创建实现类对象
4.调用重写后的方法
前提:需要存在一个接口或类
*/
public static void main(String[] args) {
// InterImp ii = new InterImp();
//ii.show();
//将继承\实现,方法重写,创建对象放在一步写
//实现了Inter接口的,一个实现类对象
new Inter(){
//为什么要放在这里面?用完就销毁了
@Override
public void show() {
System.out.println("匿名内部类中的show方法");
}
}.show();
Inter1 i = new Inter1(){
@Override
public void show1() {
System.out.println("show1");
}
@Override
public void show2() {
System.out.println("show2");
}
};
i.show1();
i.show2();
}
}
interface Inter{
void show();
}
interface Inter1{
void show1();
void show2();
}
//class InterImp implements Inter{
//
// @Override
// public void show() {
//
// System.out.println("InterImp 重写的show方法");
// }
//}
方法的参数是一个接口
Lambda表达式:
代码更少,关注点更加明确
例子:对匿名内部类进行了优化
public class Test {
public static void main(String[] args) {
/*playGame(new Game() {
@Override
public void play () {
System.out.println("DNF");
}
});*/
/* //lambda表达式的写法
//原则:能推断就省略
playGame(() ->{ System.out.println("DNF"); });
//一定是传的是"Game"接口的子类对象
//一定实现了play方法*/
playGame(() ->{
System.out.println("DNF");
});
}
//玩游戏的方法
public static void playGame(Game g){
g.play();
}
}
interface Game{
public abstract void play();
}
Lambda表达式的格式:
格 式 : ( 形 式 参 数 ) − > 代 码 块 格式:(形式参数)->{代码块} 格式:(形式参数)−>代码块
Lambda表达式本质上其实就是"匿名内部类"的简化写法.
(): 就是"重写的那个方法"的形参.
{}: 就是"重写的那个方法"的方法体.
形式参数:如果有多个参数,参数之间用逗号隔开
使用前提:"有一个接口,接口中有且只有一个抽象方法
例子:
public class Test1 {
public static void main(String[] args) {
//匿名内部类
useStringHandler(new StringHandler() {
@Override
public void printMessage(String mes) {
System.out.println("dks"+mes);
}
});
//lambda
useStringHandler((String mes) ->{
System.out.println("lambda"+mes);
});
}
public static void useStringHandler(StringHandler stringHandler){
stringHandler.printMessage("0000");
}
}
interface StringHandler{
void printMessage(String mes);
}
省略规则:
1.参数类型可以省略,但是有多个参数的情况下,不能只省略一个
2.如果参数有且只有一个,那么小括号可以省略
3.如果代码块的语句只有一条,可以省略大括号和分号,甚至是return