一、内部类:在类中定义类
(一)成员内部类:实例内部类+静态内部类
(二)局部内部类
(三)匿名内部类
(一)成员内部类
成员内部类基本知识点
成员内部类指的是类作为另一个类的一个成员。
A.实例内部类
(1)创建内部类格式
1) 先创建外部类对象;然后再在外部类对象基础上,调用内部类的所有操作,包括创建内部类。
Outer O = new Outer();
Outer.Inner i = O. new Inner();
2) 如果只创建内部类对象,外部类可以匿名,所以不用创建外部类对象,直接用匿名外部类对象new Outer()来代替。
Outer.Inner oi = new Outer().Inner();
(2)内部类成员与其他成员的访问关系:
1)内部类可以直接访问外部类的成员,包括私有,因为他们都属于外部类;
2)外部类要访问内部类的成员,必须创建对象,因为对于外部类的其他成员来说,内部类是一个并列的单独的类;
B、成员内部类私有使用
私有化后,像其他私有成员变量一样,私有内部类别的类也不能直接访问。
如果像像访问私有内部类里的方法,需在外部类内创建public方法,在public方法内创建对象,再在里面调用私有内部类的方法。
跟对私有属性创建专门的访问器是一样的。
C、成员内部类静态化后
(1)静态内部类内如果有静态成员方法 ,则沿用以前,一路直接点调用到底。
(2)静态内部类内如果有普通成员方法
调用方法:Outer.Inner oi = Outer.new Inner();;//即用类名访问 ,new 可提到前面,写为new Outer .Inner();
看作静态成员
D、变量同名时的调用方法。
//要求按顺序输出30,20,10;
class Outer{
public int num = 10 ;
class Inner {
public num = 20;
public void show(){
int num = 30;
System.out.println(num); //30
System.out.println(this.num); //20
System.out.println(Outer.this.num); //10
}
}
}
(二)局部内部类
(1)局部内部类基本知识:
类作为局部变量,即在方法中定义了一个类(用的少),只能在方法内创建对象使用,意义不大。
class Outer2 {
public void method(){
class Inner{
public void print(){
System.out.println("Hello World!");
}
}
Inner i = new Inner();
i.print();
}
}
(2)与其他成员的访问关系
访问同方法内的其他成员时,只能访问final格式常量。
局部内部类在访问他所在方法中的局部变量时必须使用final修饰?为什么
因为当调用这个方法时,局部变量如果没有用final修饰,他的声明周期和方法的声明周期是一样的,当方法弹栈,这个局部变量也会消失,但是如果局部内部类对象还没有被回收,这个时候使用这个变量就会消失,所以可能访问不到。如果用final修饰后,就会放入常量池,即使方法弹栈,常量孩子,就可以继续访问。
(三)匿名内部类(常用)
(1)匿名内部类介绍
匿名内部类其实是内部类的简化写法。用于对接口的实现或对父类的继承时只用一次,不用创建对象。好处是不用单独创建类重写方法,而是直接在创建匿名类的时候书写方法。本质上是一个没有名字的子类对象。
interface Inter {
public void print();
}
class outer {
public void method (){
new Inter(){ public void print(){
System.out.println("print");
}}.print(); //子类对象调用自己的方法。
}
}
public class NoNameInnerClass {
public static void main(String[] args) {
outer O = new outer();
O.method();
}
}
(2)匿名内部类注意:
在接口或父类中只有一个方法中用时好用,有两个以上的方法需要调用时,就应该创建有名子类:
interface Inter {
public void print1();
public void print2();
}
class outer {
public void method (){
new Inter(){
public void print1(){
System.out.println("print1");
}
public void print2(){
System.out.println("print2");
}
}.print1();
new Inter(){
public void print1(){
System.out.println("print1");
}
public void print2(){
System.out.println("print2");
}
}.print2();
}
}
或者稍微改进一点:
interface Inter {
public void print1();
public void print2();
}
class outer {
public void method (){
Inter 1 = new Inter(){
public void print1(){
System.out.println("print1");
}
public void print2(){
System.out.println("print2");
}
/*甚至当子类需要有自己的新方法时就不能用了*/
};
i.print1();
i.print2();
}
}
二、 函数式接口
只包含一个抽象方法的接口(其他方法的数量不考虑)
Lamda表达式 只能用于函数式接口
作用:替换匿名内部类的语法
()-> {};
class LaDemo{
//方法二 匿名内部类的方式
/* la a = new la(){
public void func(){
System.out.println("func");
}
};*/
//方法三 Lambda无参数无返回值
// la a1 = () -> {System.out.println("func");};
// la a2 = () -> System.out.println("func");
//无参数有返回值
/*la a1 = () -> {return 11;};
la a2 = () -> 11;*/
//形参列表
// la a1 = (m) -> {System.out.println(m);};
//带参数带返回值
//la a1 = (n)-> {return n;};
//la a1 =n-> n;
}