把定义在其他类的内部,我们称之为内部类。
2、特点(1)在内部类可以访问外部类的成员,包括私有的。
(2)外部类要访问内部类,必须要创建内部类的对象。
3、分类 (1)成员内部类:定义在外部类成员的位置上。
1)创建内部类的对象格式 外部类名.成员内部类名 对象名 = new 外部类名().new 成员内部类名();
class Outer3 {
private int num = 10;
class Inner { //成员内部类
public void show() {
System.out.println(num);
}
}
}
public class InnerClassDemo3 {
public static void main(String[] args) {
//正确创建成员内部类对象的格式
//外部类名.成员内部类名 对象名 = new 外部类名().new 成员内部类名();
Outer3.Inner oi3 = new Outer3().new Inner();
oi3.show();
Outer3 outer3 = new Outer3(); //两种都可以
Outer3.Inner inner = outer3.new Inner();
inner.show();
}
}
2)当内部类被private修饰后,其他类不能直接创建内部类的对象,要想使用被private修饰内部类成员,必须在本类中间接的创建对象调用
class Demo{
private int sum=3;
private class Sent{
public void show(){
System.out.println(sum);
}
}
public void fun(){
Sent d=new Sent(); //创建内部类对象
d.show();
}
}
public class Test1 {
public static void main(String[] args) {
Demo s=new Demo();
s.fun();
}
}
3)内部类如果是被satic修饰的时候,只能访问外部类中静态成员
static修饰的内部类创建对象格式:外部类名.内部类名 对象名 = new 外部类名.内部类名()
若内部类和内部类的成员方法都是静态的可以通过类名直接调用:外部类名.内部类名.方法名();
class Demo{
private static int sum=3;
static class Sent{
public static void show(){
System.out.println(sum);//只能访问外部类的静态成员
}
}
}
public class Test1 {
public static void main(String[] args) {
Demo.Sent a=new Demo.Sent(); //创建static修饰的内部类的对象
a.show();
Demo.Sent.show();//通过类名直接调用
}
}
4)
class Demo {
private int sum = 1;
class Sent {
public int sum = 2;
public void show() {
int sum = 3;
System.out.println(sum);
System.out.println(this.sum);
System.out.println(new Demo().sum);//可以访问到外部类的成员。
System.out.println(Demo.this.sum);//同样可以
}
}
}
public class Test1 {
public static void main(String[] args) {
Demo.Sent d=new Demo().new Sent();
d.show();
}
}
(2)局部内部类:
定义在局部范围内,外部类的成员方法内。可以访问外部类的所有成员
在外部类的方法中间接创建局部内部类的对象。
class Outer6{
private int num = 10;
public void fun(){
int num2 = 20; //在局部内部类的外部类方法中定义的局部变量默认加上final关键字
class Inner6{
int num3 = 300;
public void show(){
num3 = 30;//num2的值改不了,默认是final修饰的
num = 44;
System.out.println(num);
System.out.println(num2);
System.out.println(num3);
}
}
Inner6 inner6 = new Inner6();//在外部类的方法中创建局部内部类的对象,在测试类中调用外部类的方法即可。
inner6.show();
}
}
public class InnerClassDemo6 {
public static void main(String[] args) {
Outer6 outer6 = new Outer6();
outer6.fun();
}
}
4、匿名内部类
(1)前提:
要存在一个类或者是一个接口,这个类可以是具体的类也可以是抽象的类
(2)本质是一个继承了类或者实现了接口的子类匿名对象,相当于直接new了一个类或接口的子类,看成一个整体子类去用。
(2)定义格式new 类名(可以是抽象类也可以具体的类)/接口(){
要重写的方法;
};
利用接口多态的形式给匿名内部类起名字
A a = new A(){
b(){...}
c(){...}
};
interface Sent{
public abstract void show();
}
public class Test1 {
public static void main(String[] args) {
new Sent(){
@Override
public void show() {
System.out.println("匿名内部类");
}
}.show();
Sent a=new Sent() {
@Override
public void show() {
System.out.println("有名字的匿名内部类");
}
};
a.show();
}
}
(3)题目
按照要求,补齐代码
interface Inter { void show(); }
class Outer { //补齐代码 }
class OuterDemo {
public static void main(String[] args) {
Outer.method().show();
}
}
要求在控制台输出”HelloWorld”
interface Inter2{
void show();
}
class Outer8{
//1、根据main方法调用的代码推出第一个结论:method()是静态的,可以直接通过类名访问/调用
//2、根据main方法中调用完method()方法之后,还能继续调用方法,我们判定method()是有返回值的
//而再观察后发现,show()方法恰好是Inter2接口中的方法,所以返回值类型是接口Inter2类型
//根据调用method()方法的参数是空,所以判定method()方法没有参数
public static Inter2 method(){
return new Inter2() {
@Override
public void show() {
System.out.println("HelloWorld");
}
};
}
}
public class InnerClassDemo9 {
public static void main(String[] args) {
Outer8.method().show();
}
}



