一.内部类概述
- 内部类:在一个类中定义另一个类,内部类
举例:在A类中定义了一个B类,B就是A类的内部类,A类叫做外部类 - 内部类的分类:
- 成员内部类:在外部类的成员位置
- 局部内部类:在外部类的局部位置
- 内部类的访问特点:
- 内部类可以直接访问外部类的成员,包括私有
- 外部类不能直接访问内部类的成员,需要在内部类对象,通过内部类对象使用方法
//外部类
class A{
//成员变量
int num1 = 10;
private int num2 = 20;
//成员内部类
class B{
int num3 = 30;
public void show(){
//内部类可以直接访问外部类的成员,包括私有
System.out.println(num1);
System.out.println(num2);
}
}
public void method(){
//报错,外部类不能直接访问内部类成员
// System.out.println(num3);
// show();
//需要通过创建内部类对象来访问
B b = new B();
System.out.println(b.num3);
b.show();
}
}
//测试类
public class Demo1 {
public static void main(String[] args){
A a = new A();
a.method();
}
}
二.成员内部类
1.可以直接访问外部类的成员,包括私有
2.不能直接访问内部类的成员,需要在内部类对象,通过内部类对象使用方法
3.成员内部类的访问:不能直接创建对象
非静态内部类访问格式:外部类名.内部类名 对象名 = 外部对象.内部类对象;
静态内部类访问格式:外部类名.内部类名 对象名 = new 外部类名.内部类名();
//外部类
class A1{
//成员内部类
class B1{
int num = 30;
public void show(){
System.out.println(num);
}
}
}
//测试类
public class Demo2 {
public static void main(String[] args){
//报错,内部类的访问不能直接创建对象
// B1 b = new B1();
A1.B1 c = new A1().new B1();
c.show();
}
}
4.成员内部类的常见修饰符:
a.pirvate
:保护数据的安全性
b.static
:为了让数据访问更方便
注意:被静态修饰的成员内部类只能访问外部类的静态成员
被private修饰的成员内部类:
class Body{
//私有的成员内部类
private class Heart{
public void show(){
System.out.println("心脏");
}
}
public void method(){
Heart h = new Heart();
h.show();
}
}
//测试类
public class Demo3{
public static void main(String[] args){
//报错,私有的成员内部类,不能直接创建对象
// Body.Heart ah = new Body().new Heart();
Body b = new Body();
b.method();
}
}
被static修饰的成员内部类:
class Number{
public int num1 = 10;
public static int num2 = 20;
//被static修饰的成员内部类
public static class Num{
public int num3 = 30;
public static int num4 = 40;
//非静态方法
public void show(){
//报错,静态内部类访问的外部类成员必须是静态的
// System.out.println(num1);
System.out.println(num2);
}
//静态方法
public static void method(){
//报错,静态内部类访问的外部类成员必须是静态的
// System.out.println(num1);
System.out.println(num2);
}
}
}
public class Demo4 {
public static void main(String[] args){
//成员静态内部类访问自己的格式
//方式一:可以访问静态和非静态的成员
Number.Num n = new Number.Num();
System.out.println(n.num3);
System.out.println(n.num4);
n.show();
n.method();
//方式二:访问静态成员
Number.Num.method();
System.out.println(Number.Num.num4);
//报错,只可访问静态成员
// System.out.println(Number.Num.num3);
}
}
三.局部内部类
- 可以直接访问外部类的成员
- 可以创建内部类对象,通过对象调用内部类方法,来使用局部内部类功能
- 局部内部类访问局部变量的注意事项:
必须被final
修饰
原因:
因为局部变量会随着方法的调用完毕而消失,这个时候,局部对象并没有立马从堆内存中消失,还要使用那个变量.为了让数据还能继续被使用,就用fianl修饰,这样,在堆内存里面存储的其实是一个常量值.
三.匿名内部类
1.前提条件:有一个类或者接口存在(这个类可以是具体类也可以是抽象类)
2.格式:
new 类名/接口名(){
方法重写;
} ;
3.匿名内部类的本质:需要继承该类或者实现该接口的子类对象
内部类与外部类没有继承关系
接口不能直接实例化:
a.创建子实现类型:通过接口多态的形式去访问
b.使用匿名内部类去访问
//接口
interface Inter{
public abstract void show();
public abstract void show2();
}
//外部类
class Outer{
public void method(){
//调用一个方法:show()方法
new Inter(){
public void show(){
System.out.println("show..");
}
public void show2() {
System.out.println("show2..");
}
}.show();
//调用一个方法:show2()方法
new Inter(){
public void show2(){
System.out.println("show2..");
}
public void show() {
System.out.println("show..");
}
}.show2();
//一次性调用
Inter i = new Inter(){
public void show(){
System.out.println("show..");
}
public void show2() {
System.out.println("show2..");
}
};
i.show();
i.show2();
}
}
public class Demo5 {
public static void main(String[] args){
Outer o = new Outer();
o.method();
}
}
4.匿名内部类的一些问题:
a.补齐代码:在控制台分别输出:30,20,10
class Outer1{
public int num = 10 ;
class Inner1{
public int num = 20 ;
public void method(){
int num = 30 ;
}
}
}
public class Demo6{
public static void main(String[] args) {
Outer1.Inner1 oi = new Outer1().new Inner1();
oi.method();
}
}
补齐:
class Outer1{
public int num = 10 ;
//成员内部类
class Inner1{
public int num = 20 ;
public void method(){
int num = 30 ;
//就近原则,直接输出30
System.out.println(num);
//使用本类对象直接输出20
System.out.println(this.num);
//使用匿名对象访问外部类的num
System.out.println(new Outer1().num);
//使用外部累名.this去调用成员变量(外部类限定this)
// System.out.println(Outer1.this.num);
}
}
}
public class Demo6{
public static void main(String[] args) {
Outer1.Inner1 oi = new Outer1().new Inner1();
oi.method();
}
}
b.补齐代码:要求在控制台输出:HelloWorld
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
补齐:
interface Inter2 {
void show();
}
class Outer2 {
public static Inter2 method(){
return new Inter2(){
public void show(){
System.out.println("HelloWorld");
}
};
}
}
class Demo7{
public static void main(String[] args) {
Outer2.method().show();
}
}