局部内部类的使用
代码走向流程:
1,实例化Outer02,调用Outer02的公共方法m1()
2,m1()方法实例化Inner02局部类
3,Inner02调用f1()方法
- 输出局部内不类的私有属性n1,外部类需要Outer02.this.n1调用
- 调用Outer02.this输出Outer02对象地址
- 调用外部类的私有属性m2()
总结:
1,局部内部类是定义在外部类的局部位置,比如方法中,并有类名。
2,可以直接访问外部类的所有成员,包含私有的
3,不能添加访问修饰符,因为它的地位就是一个局部变量,局部变量不能使用访问修饰符。但是可以使用final修饰,因为局部变量可以使用final
4,作用域:仅定义在它的方法或代码块中。
5,局部内部类定义在方法或者代码块中
6,外部其他类不能访问局部内不类(因为局部内部类地位是一个局部变量)
7,如果外部类和局部内部成员成名时,默认遵循就近原则,如果访问外部类的成员,可以使用(外部类.this.成员)去访问
/**
* 局部内部类
*/
public class LocalInnerClass {
public static void main(String[] args) {
//演示一遍
Outer02 outer02 = new Outer02();
outer02.m1();
System.out.println("outer02 的 hashcode=" + outer02);
}
}
class Outer02 {//外部类
private int n1 = 100;
//私有方法
private void m2() {
System.out.println("Outer02 m2()");
}
public void m1() {//方法
//1.局部内部类是定义在外部类的局部位置,通常在方法
//3.不能添加访问修饰符,但是可以使用 final 修饰
//4.作用域 : 仅仅在定义它的方法或代码块中
final class Inner02 {//局部内部类(本质仍然是一个类)
//2.可以直接访问外部类的所有成员,包含私有的
private int n1 = 800;
public void f1() {
//5. 局部内部类可以直接访问外部类的成员,比如下面 外部类 n1 和 m2()
//7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,
// 使用 外部类名.this.成员)去访问
// 老韩解读 Outer02.this 本质就是外部类的对象, 即哪个对象调用了 m1, Outer02.this 就是哪个对象
System.out.println("n1=" + n1 + " 外部类的 n1=" + Outer02.this.n1);
System.out.println("Outer02.this hashcode=" + Outer02.this);
m2();
}
}
//6. 外部类在方法中,可以创建 Inner02 对象,然后调用方法即可
Inner02 inner02 = new Inner02();
inner02.f1();
}
}
匿名内部类
1.匿名内部类的使用
介绍:
1,本质是类,内部类,该类没有名字,同时还是一个对象
2,匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名
3,匿名内部类的基本语法
new 类或者接口(参数列表){
类体
};
案例:
1,基于接口的
2,基于类的
3,基于抽象类的
/**
* 匿名内部类
*/
public class AnonymousInnerClass {
public static void main(String[] args) {
Outer04 outer04 = new Outer04();
outer04.method();
}
}
class Outer04 { //外部类
private int n1 = 10;//属性
public void method() {//方法
//1,基于接口的匿名内部类
IA tiger = new IA() {
@Override
public void cry() {
System.out.println("老虎叫唤...");
}
};
//运行类型=class com.wyk.innerclass15.Outer04$1
//Outer04$1 匿名内部类名字是系统分配的
System.out.println("运行类型=" + tiger.getClass());
//匿名内部类使用一次就不能使用了,对象可以无限使用
tiger.cry();
tiger.cry();
tiger.cry();
//2,基于类的匿名内部类
// father1运行类型是Father
// Father father1 = new Father("你好");
// System.out.println(father1.getClass());
Father father2 = new Father("你好") {
@Override
public void test() {
System.out.println("你好啊!!");
}
};
//father2运行类型Outer04$2
System.out.println("father2运行类型" + father2.getClass());
//调用方法
father2.test();
}
//3,基于抽象类的匿名内部类演示
Animal animal = new Animal(){
@Override
void eat() {
System.out.println("重写抽象类的方法!!");
}
};
}
interface IA {//接口
public void cry();
}
class Father {//类
public Father(String name) {//构造器
//传递给Father 构造器
System.out.println("接收到 name=" + name);
}
public void test() {//方法
}
}
abstract class Animal { //抽象类
abstract void eat();
}
2. 细节
1,匿名内部类即是一个类的定义,同时本也是一个对象,因此可以调用匿名内部类方法。
2,其他使用细节和局部内部类一样。
/**
* 匿名内部类使用细节
*/
public class AnonymousInnerClassDetail {
public static void main(String[] args) {
Dog dog = new Dog();
dog.method2();
}
}
class Dog{
private String name;
private void method1(){
System.out.println("小花狗");
}
public void method2(){
new GG(){
@Override
public void gg() {
System.out.println("重写gg");
System.out.println(Dog.this.name);
}
}.gg(); //直接调用方法输出
}
}
class GG{
public void gg(){
System.out.println("gg()");
}
}
3. 当做实参直接传递
/**
* 匿名内部类当做实参传递
*/
public class AnonymousTest {
public static void main(String[] args) {
a1(new Person() {
@Override
public void p() {
System.out.println("66666");
}
});
}
public static void a1(Person person) {
person.p();
}
}
interface Person {
public void p();
}
成员内部类的使用
1,成员内部类调用在外部类的成员位置,并且没有static修饰。
2,可以访问外部类的所有成员,包含私有,如过外部属性和内部属性名一样可以用外部类名.this.属性名区别
3,可以添加任意访问修饰符和普通成员一样。
4,作用域:和其他成员一样整个类体
三种方法调用成员内部类
/**
* 成员内部类
*/
public class MemberInnerClass {
public static void main(String[] args) {
//调用方法
// Outer08 outer08 = new Outer08();
// outer08.h1();
//类调用成员内部类
// Outer08.inner08 inner08 = outer08.new inner08();
// inner08.say();
//调用方法创建的实例
// Outer08.inner08 inner081 = new Outer08().getInner08();
// inner081.say();
}
}
class Outer08 { //外部类
private int n1 = 10;
public String name = "张三";
private void hi() {
System.out.println("hi()方法...");
}
//成员内部类 ,可以添加任意访问修饰符 ,因为它本身就是一个成员
public class inner08 {
private String name;
public void say() {
//可以直接访问外部类的所有成员包括私有,访问外部属性 方法名.this.属性名
System.out.println(n1 + name+Outer08.this.name);
hi();
}
}
//方法中实例对象
public void h1() {
inner08 inner08 = new inner08();
inner08.say();
}
//返回inner08对象
public inner08 getInner08(){
return new inner08();
}
}
静态内部类的使用
1,静态内部类定义在成员位置,有static修饰
2,可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员,外部属性内部属性重名时候,外部类.成员去访问,其他遵循就近原则
3,可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
4,作用域 :同其他的成员,为整个类体,
三种方法调用静态内部类
/**
* 静态内部类
*/
public class StaticInnerClass01 {
public static void main(String[] args) {
// 调用方法实列化
// StaticTest staticTest = new StaticTest();
// staticTest.s3();
//类调用静态内部类
// StaticTest.inner09 inner09 = new StaticTest.inner09();
// inner09.s2();
//编写一个方法,可以返回静态内部类的对象实例.
StaticTest.inner09 inner09 = new StaticTest().getInner09();
inner09.s2();
}
}
class StaticTest {
private static String name = "你是";
public static void s1() {
System.out.println("静态方法s1()");
}
//静态内部类
//3. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
//4. 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
//5. 作用域 :同其他的成员,为整个类体
public static class inner09 {
private static String name = "你是谁!!";
public void s2() {
System.out.println("访问外部的静态成员=" + StaticTest.name);
System.out.println("访问内部的静态成员=" + name);
s1();
}
}
public void s3(){
inner09 inner09 = new inner09();
inner09.s2();
}
public inner09 getInner09(){
return new inner09();
}
}