1.内部类
(1)内部类:在B类内部定义A类,A类就属于B的内部类
内部类访问外部类的特点:
它可以直接访问外部类的成员,包括私有
外部类如何访问内部类的成员?
在外部类的成员方法中,通过创建内部类对象的方式间接访问...
class Outer{
int num = 100 ;
private int num2 = 200 ;
//Inner就是Outer的内部类
class Inner{
//内部类的方法
public void show() {
System.out.println(num);
System.out.println(num2);
}
}
//外部类的成员位置
public void method() {
//show() ;
//只能创建内部类对象的方式
Inner i = new Inner() ;
i.show();
}
}
(2)内部类的分类
1)成员内部类:在外部类的成员位置
class Outer{
//在成员位置:成员内部类
class Inner2{
}
}
2)局部内部类:在外部类的局部位置
class Outer{
public void method() {
//在局部位置:局部内部类
class Inner{
}
}
}
(3) 成员内部类:
1)可以直接外部类的成员,包括私有
外部类要访问内部类(非静态的内部类)的成员方法:
格式:外部类名.内部类名 对象名 = new 外部类对象.new 内部类对象
class Outer{
//外部类的成员变量
private int num = 10 ;
//成员内部类
class Inner{
//show()
public void show() {
System.out.println(num);
}
}
}
问题:外部类Outer如何访问内部类Inner中的show()方法?
//测试类
public class OuterDemo {
public static void main(String[] args) {
// 格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象
Outer.Inner oi = new Outer().new Inner();
oi.show();
}
}
2)关于成员内部类的修饰符:
private修饰: 作用:保证数据的安全性!
static修饰:可以把静态内部类看成是外部类的成员.
特点: 静态成员内部类访问外部类的数据,该数据必须static修饰
3)对于外部类访问静态的成员内部类的访问格式
外部类名.内部类名 对象名 = new 外部类名.内部类名() ; //把静态的成员内部类看成了外部类的成员
(4)局部内部类
1)可以访问外部类的成员包括私有...
在外部类的局部位置去访问内部类的show(),需要在局部位置创建内部了对象,通过对象去访问
2)局部内部类访问局部变量
//定义外部类
class Outer{
private int num = 10 ;
//定义外部类的成员方法
public void method() {
//变量
int num2 = 20 ; //jdk1.8不会有问题..
//定义局部内部类
class Inner{
public void show() {
System.out.println(num);
//注意事项:在这块改变量继续被使用...将变量变成固定值:在内存始终存在(被内部类的成员去使用)
System.out.println(num2);
}
}
}
}
面试题:
局部内部类访问局部变量,那么会出现问题?(jdk7以前包括jdk7,这个有问题的)
会报错,需要给局部变量添加final修饰...(jdk1.8不会有问题...)
2.匿名内部类
(1)前提是有一个类或者接口
这个类可以是具体类也可以是抽象类
new 类名或者接口名{
方法重写();
}
(2) 匿名内部类的本质:
是继承了该类或者实现了该接口子类对象...
//定义一个接口
interface Inter{
public abstract void show();
}
1)调用接口一个方法的时候
//定义一个类实现这接口...
class Outer{
//成员方法
public void method() {
//调用接口一个方法的时候:匿名内部类的形式
new Inter() {
@Override
public void show() {
System.out.println("show...");
}
}.show();
}
}
2)两个方法调用
class Outer{
//成员方法
public void method() {
//两个方法调用
//直接创建对象,给它起名字
Inter i = new Inter() {
@Override
public void show2() {
System.out.println("show2...");
}
@Override
public void show() {
System.out.println("show....");
}
};
i.show();
i.show2();
}
}
(3)实际开发中,接口作为形式参数的问题
如果形式参数是接口:
传统的方式: 1)提供给接口的子实现类 2)内部类的方式(不需要提供子实现类)
如:
interface Inter{
public abstract void study();
}
//具体类
class StudentDemo{
public void method(Inter i) {//Inter i = new Inter() ;//错误
i.study();
}
}
1)提供给接口的子实现类
class InterImpl implements Inter{
@Override
public void study() {
System.out.println("好好学习,天天向上...");
}
}
//测试类
public class Demo {
public static void main(String[] args) {
//需求:需要调用StudentDemo这个类中method()方法
StudentDemo sd = new StudentDemo() ;
//接口多态的形式
Inter i = new InterImpl() ;
sd.method(i);
System.out.println("---------------");
}
}
2)内部类的方式(不需要提供子实现类)
//测试类
public class Demo {
public static void main(String[] args) {
//需求:需要调用StudentDemo这个类中method()方法
Inter i = new Inter() {
@Override
public void study() {
System.out.println("好好学习,天天向上...");
}
};
i.study();
}
}
(4) 匿名内部类面试题:
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
分析:
Outer.method() :当前这个method方法是静态方法
Outer.method().show(); //Outer.method()---->返回一个对象.show(),又由于show()方法是一个接口中的方法,返回值是一个接口类型
class Outer{
//补齐代码
public static Inter method() {
//返回的是接口:当前并不提供接口的子实现类,所以只能用匿名内部类
return new Inter() {
public void show() {
System.out.println("HelloWorld");
}
};
}
}