内部类 :
类中定义类
一, 成员内部类 :
1. 所处位置:
内部类定义在外部类的成员位置
public class Class001_Outer {
//成员内部类
class Inner {
//成员变量
public int a = 10;
static final int b = 20;
public Inner() {
}
public Inner(int a) {
this.a = a;
}
//成员方法
public void inner(){
System.out.println("内部类的成员方法");
System.out.println(i);
System.out.println(j);
}
}
}
2.同时具有类和成员的特点
可以被成员修饰符所修饰,可以继承其他父类,实现需要的接口,具有成员的特点,具有类的特点
3.特点 :
在成员内部类中只能定义非静态的成员内容,除了静态的常量
在成员内部类中可以直接使用所在外部类的成员,包括私有的
在所在外部类中需要通过成员内部类的对象访问其成员(包括私有成员),可以通过类名访问其静态的常量
public void outer(){
System.out.println("外部类中的成员方法");
System.out.println(Inner.b);
//成员内部类对象
Inner in = new Inner();
System.out.println(in.a);
in.inner();
}
在其他类中需要 通过外部类创建成员内部类对象,通过成员内部类对象访问其成员
//测试成员内部类的使用
//外部类对象
//Class001_Outer outer1 = new Class001_Outer();
//根据外部类对象创建内部类对象
//Class001_Outer.Inner in1 = outer1.new Inner();
Class001_Outer.Inner in1 = new Class001_Outer().new Inner();
二,私有内部类 :
被private修饰的成员内部类
私有内部类中可以直接使用外部类的成员,包括私有的
在所在外部类中,通过私有内部类的对象访问其成员
其他类中无法使用私有内部类
public class Class003_Outer {
//外部类的成员变量和静态变量
private int i=1;
private static int j=2;
//私有内部类
private class Inner{
//私有内部类的私有属性
private int m=0;
//私有内部类中也不能有静态的内容
//private static int n=0;
//内部类的成员的方法
public void inner(){
System.out.println("我是内部类的成员方法");
System.out.println(i);
System.out.println(j);
}
}
//外部类的成员变量
public void outer(){
//调用内部类的成员变量和私有的属性
Inner inner=new Inner();
//可以通过内部类对象调用内部类的私有属性
System.out.println(inner.m);
}
}
三,静态内部类 :
被static修饰的内部类
静态内部类中可以根据需求定义静态|非静态的成员
在静态内部类中可以直接使用所在外部类的静态内容,需要通过外部类的对象访问其成员
在所在外部类中可以通过类名访问静态内部类中静态内容,需要通过对象访问静态内部类中的成员
在其他类中可以通过外部类类名.内部类类名.静态内容访问静态内部类中的静态内容
在其他类中可以通过new 外部类类名.内部类类名()的内部类对象访问静态内部类中的成员内容
public class Class004_Outer {
//外部类的成员变量
private int i;
private static int j;
//静态的内部类
static class Inner{
//静态内部类的成员变量
//静态内部类中可以根据需求定义静态的和非静态的内容
private int m;
private static int n;
//成员方法
//静态的成员方法
public static void inner1(){
//静态的内部类成员方法不能直接调用外部类的成员变量
//System.out.println(i);
//静态内部类可以直接访问外部类的静态内容
System.out.println(j);
}
//内部类的成员方法
public void inner2(){
//内部类的成员方法也不能直接访问外部类的成员变量,因为这个类就是静态的
//System.out.println(i);
System.out.println(j);
}
}
//外部类的成员方法
public void outer(){
//外部类要通过对象调用静态内部类的成员变量
//可以通过类名.变量名调用静态内部类的静态内容
System.out.println("我是外部类的成员变量");
System.out.println(Inner.n);
Inner inner1=new Inner();
System.out.println(inner1.m);
}
}
四,局部内部类 :
定义在方法中,内部类为局部内部类
局部内部类中只能定义非静态的成员内容,除了静态的常量
在局部内部类中可以使用所在外部类的成员
局部内部类中如果一旦使用所在方法的局部变量(参数),这个局部变量必须为常量
jdk7及之前 : 要求必须手动被final修饰
jdk8及之后 : 默认被final修饰
只能在所在的方法中通过对象访问局部内部类的成员,在外部类中的其他方法中|其他类中都无法使用局部内部类
public class Class005_Outer {
//外部类的成员变量
private int i;
private static int j;
public void test(){
int m=0;
//局部内部类
class Inner{
//局部内部类里面定义的变量一定为常量
private int q=0;
//局部内部类中不能定义静态的内容
//private static int h;
//局部内部类的成员方法
public void inner(){
System.out.println(m);
System.out.println(i);
System.out.println(j);
//被调用的局部内部类的成员变量默认被final修饰
System.out.println(q);
}
}
//所在方法内部调用内部类成员
//要通过对象调用
Inner inner=new Inner();
System.out.println(inner.q);
}
//外部类的成员方法
//测试局部内部类
public void outer(){
//局部内部类只能在所在的方法体中使用
//在其他类和外部类的成员方法中不能使用
}
}
五,匿名内部类
匿名内部类 :
1.匿名内部类的作用
简化一些满足条件要求的实现类|子类,将定义实现类重写方法+创建实现类对象两步合并成一步
1)类没有自己本身作用
2)实现类|子类只在当前使用一次,不会重复使用多次
2,语法 :
new 接口|抽象类(){--->实现类|子类类体
重写方法....
};
public class Class006_Outer {
public static void main(String[] args) {
//匿名对象,对象只使用一次
new Swim(){
@Override
public void swim() {
System.out.println("匿名对象的方法重写");
}
};
//引用指向对象
Swim swim=new Swim() {
@Override
public void swim() {
System.out.println("有引用指向的匿名对象的方法重写");
}
};
//作为方法的形参
testSwim(new Swim() {
@Override
public void swim() {
System.out.println("testSwim参数里面的方法重写");
}
});
}
//定义一个方法,形参为Swim类型
public static void testSwim(Swim swim) {
System.out.println("调用了testSwim方法");
swim.swim();
}
}
//接口
interface Swim{
void swim();
}
//实现类
class Demo implements Swim{
@Override
public void swim() {
System.out.println("实现类的方法重写");
}
}
3,lambda表达式
lambda表达式 : *****
jdk1.8新特性之一
3.1作用 : 简化满足条件的匿名内部类对象
3.2前提 : 函数式接口
3.2.1函数式接口 : 抽象方法只有一个
3.2.2如何检查一个接口是否为函数式接口 : @FunctionalInterface
语法 :
()->{}
() : 重写方法的参数列表
-> : 箭头函数 | lambda符号
{} : lambda体-->重写方法的方法体
3.3注意 :
以后看到方法的形参|引用的引用的类型为函数式接口的时候,那么传递实参|为引用赋值就可以通过lambda表达式进行实现
package homework.homework0227.lambda;
public class Class001_Lambda {
public static void main(String[] args) {
//匿名内部类
Smoke s=new Smoke() {
@Override
public void smoke() {
System.out.println("普通匿名内部类中的方法重写");
}
};
s.smoke();
//lambda方法一
s=()->{
System.out.println("方法一的方法重写");
};
s.smoke();
//lambda方法二
s=()-> System.out.println("方法二的方法重写");
//lambda方法三
Swim ss=(name)-> System.out.println("方法三的方法重写");
//lambda方法四
ss=name-> System.out.println("方法四的方法重写");
//lambda方法五
//只有一个语句并且是带出返回值的,省略前后的{}和return关键字
Eat e=name -> name;
System.out.println(e.eat("haha"));
System.out.println(e.eat("xixi"));
}
}
//定义一个接口
interface Smoke{
void smoke();
}
//定义一个方法带参数的接口
interface Swim{
void Swim(String name);
}
//定义一个接口中的方法有返回值
interface Eat{
String eat(String name);
}
//定义一个实现类
class Demo implements Smoke{
@Override
public void smoke() {
System.out.println("实现类Demo里面的重写方法");
}
}