内部类
定义:
一个类的内部又完整的嵌套了另一个类结构,被嵌套的类就被我们称为内部类,嵌套内部类的类被我们称为外部类
//外部类
class Outer
{
//内部类
class Inner
{
}
}
package Innerclass;
//外部其他类
public class c1 {
}
class Outer
{
//属性
private int n1 = 100;
//方法
public void m1()
{
System.out.println("m1()");
}
//内部类
class Inner
{
}
}
内部类的分类
1、定义在外部类局部位置上(比如方法内)
(1)局部内部类(有类名)
(2)匿名内部类(没有类名)
2、定义在外部类的成员位置上
(1)成员内部类(没用static修饰)
(2)静态内部类(使用static修饰)
1、局部内部类
1、局部内部类是定义在外部类的方法中的
2、并且局部内部类可以访问外部类的所有成员包括私有的,访问的方法是直接访问,外部类在方法中可以创建内部类的对象,然后通过内部类的对象去调用其方法
3、不能添加访问修饰符,和局部变量一样,可以用final来修饰
4、作用域只在局部类的方法体内
5、外部其他类不能访问局部内部类(因为局部内部类的地位是一个局部变量)
package Innerclass;
public class LocalInnerClass {
public static void main(String []args)
{
Outer02 outer02 = new Outer02();
outer02.m1();
}
}
//外部类
class Outer02
{
//属性
private int n1 = 100;
//私有方法
private void m2()
{
System.out.println("m2");
}
//方法
public void m1()
{
//局部内部类通常定义在外部类的方法中
//局部内部类
class Inner02
{
//局部内部类可以访问外部类的所有成员,包含私有的
public void f1()
{
m2();
System.out.println("n1 = " + n1);
}
}
Inner02 inner02 = new Inner02();
inner02.f1();
}
}
6、如果外部类和内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员可以使用(外部类名.this.成员)
Out02.this.n2
匿名内部类
1、本质是类
2、内部类, 但实际是有名字的,只不过用完之后会立即被销毁
3、该类是没有名字
4、同时还是一个对象
匿名内部类创建之后,会立马实例化出来,然后这个匿名类内部类就不能再被使用了,但实例化出来的对象是可以反复调用的
基于接口的匿名内部类使用
package Innerclass;
public class AnonymousInnerClass {
public static void main(String []args)
{
Outer04 outer04 = new Outer04();
outer04.method();
}
}
class Outer04
{
private int n1 = 10;
public void method()
{
//基于接口的匿名内部类
//tiger的编译类型?IA
//tiger的运行类型?就是匿名内部类
/*
底层是
class XXXX implements IA
{
public void cry()
{
System.out.println("老虎叫唤...");
}
}
*/
IA tiger = new IA()
{
public void cry()
{
System.out.println("老虎叫唤...");
}
};
System.out.println("tiger的运行类型 = " + tiger.getClass());
tiger.cry();
}
}
interface IA{
public void cry();
}
基于类的匿名内部类
package Innerclass;
public class AnonymousInnerClass {
public static void main(String []args)
{
Outer04 outer04 = new Outer04();
outer04.method();
}
}
class Outer04
{
private int n1 = 10;
public void method()
{
//基于接口的匿名内部类
//tiger的编译类型?IA
//tiger的运行类型?就是匿名内部类
/*
底层是
class XXXX implements IA
{
public void cry()
{
System.out.println("老虎叫唤...");
}
}
*/
IA tiger = new IA()
{
public void cry()
{
System.out.println("老虎叫唤...");
}
};
System.out.println("tiger的运行类型 = " + tiger.getClass());
tiger.cry();
//正常new一个对象
Father father1 = new Father();
System.out.println("father1对象的运行类型是=" + father1.getClass());
//匿名内部类
Father father = new Father()
{
@Override
public void test() {
System.out.println("匿名内部类重写了test方法");
}
};
System.out.println("father对象的运行类型=" + father.getClass());
father.test();
Animal animal = new Animal()
{
@Override
public void say() {
System.out.println("小狗吃骨头");
}
};
animal.say();
}
}
interface IA{
public void cry();
}
class Father
{
public void test() {}
}
abstract class Animal
{
public void say()
{}
}
匿名内部类的使用细节
匿名内部类的定义比较特殊,本身是一个类同时还是一个对象
先定义一个匿名内部类,接收之后,再用生成的对象
不接收直接调用
package Innerclass;
public class AnonymousInnerClassDetail
{
public static void main(String[] args)
{
Outer05 outer05 = new Outer05();
outer05.f1();
}
}
class Outer05
{
private int n1 = 99;
public void f1()
{
Person person = new Person()
{
@Override
public void hi() {
System.out.println("匿名内部类重写了hi");
}
};
person.hi();
//也可以直接调用
new Person()
{
@Override
public void hi() {
System.out.println("匿名内部类重写了hi");
}
}.hi();
}
}
class Person
{
public void hi()
{
System.out.println("Person hi");
}
}
匿名内部类的实践
匿名内部类主要用于当前类只使用一次,使用过后我们就不会再反复使用,这样我们就没有必要专门再写一个类。
package Innerclass;
public class InnerClassExercise01 {
public static void main(String[]args)
{
f1(new IL() {
@Override
public void show() {
System.out.println("这是一幅名画");
}
});
}
public static void f1(IL il)
{
il.show();
}
}
interface IL
{
void show();
}
package Innerclass;
public class InnerClassExercise02 {
public static void main(String[] args)
{
CellPhone cellPhone = new CellPhone();
cellPhone.alarmclock(new Bell() {
@Override
public void ring() {
System.out.println("懒猪起床了");
}
});
cellPhone.alarmclock(new Bell() {
@Override
public void ring() {
System.out.println("小伙伴们上课");
}
});
}
}
interface Bell
{
void ring();
}
class CellPhone{
public void alarmclock(Bell bell)
{
bell.ring();
}
}
成员内部类
1、成员内部类是定义在外部类的成员位置,并且没有static修饰。
2、成员内部类可以直接访问外部类的所有成员,包括私有成员。
3、外部类访问内部类,就是直接创建一个内部类然后通过类进行访问。
4、我们可以用public、private、protected去修饰,因为它本身就是一个成员
。
package Innerclass;
public class MemberInnerClass {
public static void main(String [] args) {
Outer08 outer08 = new Outer08();
outer08.t1();
}
}
class Outer08{
private int n1 = 10;
public String name = "张三";
class Inner08{
public void say()
{
System.out.println("n1 = " + n1 + " name = " + name);
}
}
public void t1(){
Inner08 inner08 = new Inner08();
inner08.say();
}
}
外部其他类使用成员内部类的两种方式
1、
2、
静态内部类
比上个内部类多了一个static修饰符
1、静态内部类,在外部类的成员位置,有static修饰
2、可以访问外部类的所有静态成员,非静态不能访问
3、作用域为整个类体
package Innerclass;
public class StaticInnerClass {
public static void main(String[] args) {
Outer10 outer10 = new Outer10();
outer10.m1();
}
}
//外部类
class Outer10{
private int n1 = 10;
private static String name = "张三";
//静态内部类,在外部类的成员位置,有static修饰
//可以访问外部类的所有静态成员,非静态不能访问
//作用域为整个类体
static class Inner10{
public void say(){
System.out.println(name);
}
}
public void m1(){
Inner10 inner10 = new Inner10();
inner10.say();;
}
}