(内部类篇)面试不用愁!一文带你彻底了解内部类

内部类的概念
内部类的分类成员内部类
静态内部类
局部内部类
匿名内部类

内部类的概念

什么是内部类:

  • 定义在类内部的类
public class Test {
	class innerClass{	//内部类
		public void method() {
			System.out.println("innerClass");
		}
	}
}
返回顶层目录

内部类的分类

成员内部类:

  • 定义在类内部的非静态类,就是成员内部类。

实例内部类是 属于对象的内部类,是 不属于类的,不使用static修饰的内部类

  • 意思就是把这玩意儿看成是一个对象,别把他当类看

内部类 可以 访问 外部类 当中的成员;
外部类 不能 直接访问 内部类 当中的成员

  • 意思是 我们要把‘实例内部类’看作对象,而不是类,因此内部类中的成员变量不能使用static修饰,因为static是属于‘类’的 字段和方法,而实例内部类是对象。如果强行写上,编译器会报错。

内部类 可以 访问 外部类 当中的成员
外部类 不能 直接访问 内部类 当中的成员

  • 意思是 我们要把‘实例内部类’看作对象,而不是类,因此内部类中的成员变量不能使用static修饰,因为static是属于‘类’的 字段和方法,而实例内部类是对象。如果强行写上,编译器会报错。
package test2;

class Outter {
	String name = "OutterName";
	
	class InnerClass{	//内部类
//			static int  a;	//不能为static
//			final int a;
			
			String name = "Chenny";
			void testFuc() {
				String name  = "testName";
				System.out.println(name);	//方法内的name
				System.out.println(this.name);	//内部类中的name
				System.out.println(Outter.this.name);	//外部类中的name
			}
	}
}


public class Test{
	public static void main(String[] args) {
		Outter o = new Outter();
		System.out.println(o.name);
//		InnerClass in = new InnerClass();
		Outter.InnerClass in = o.new InnerClass();
		in.testFuc();
	}
}

返回顶层目录

静态内部类

静态内部类:

  • 静态内部类是 在内部类前面加上static,静态内部类是 不需要创建外部对象。
    Outter.InnerClass in = new Outter.InnerClass();

在静态内部类当中, 没有外部类引用

  • 意思是他在堆中开辟的空间 里面没有存放外部类的地址

静态内部类,是可以访问外部类的静态成员

  • 但是不能直接访问外部类中的非静态成员变量
  • 如果想要访问外部类中的非静态成员变量 可以new一个外部类出来:new Outer().age

访问静态内部类当中的静态成员:Outter.Inner.color

  • 不需要new内部类,直接把内部类当对象用

静态内部类当中不仅可以定义静态成员也可以定义非静态成员

class Outter {	
	int a = 10;
	static int b = 11;
	final int c = 12;
	
	static class InnerClass{			
			String name = "Chenny";
			void testFuc() {
				String name  = "testName";
				System.out.println(name);	//方法内的name
				System.out.println(this.name);	//内部类中的name
//				System.out.println(a);	//Error
				System.out.println("b = " + b);
//				System.out.println("c = " + c);	//Error
			}
	}
}

public class Test{
	public static void main(String[] args) {
		Outter.InnerClass in = new Outter.InnerClass();
		in.testFuc();
	}
}

返回顶层目录

局部内部类

局部内部类:

  • 定义在方法中的内部类。
  • 不能使用一些修饰符public private…
  • 局部内部类只能定义在方法当中使用
  • 局部内部类当中是不能包含静态变量
  • 因为局部内部类是‘属于方法的’,而static是‘属于类的’,两者相矛盾

局部内部类当中可以包含局部变量,使用的局部变量的本质是final变量

  • 在方法中new出局部类,会在堆中开辟空间,若局部内部类使用了栈中该方法栈帧的成员变量,一旦方法栈帧出栈,堆中的成员变量就无法找到指向的元素,会空指针异常
    为了避免这种情况,只能将方法中的成员变量设为static或final,但是static又不能设,所以只能设置为final

class People {
	public People() {

	}
}

class Man {
	public Man() {
	}

	public People getWoman() {
		class Woman extends People { // 局部内部类
			int age = 0;
		}
		return new Woman();
	}
}
返回顶层目录

匿名内部类

匿名内部类:

  • 它连名字都没有 所以也没有构造器 一个文件对应一个类
  • 只使用一次的时候,就使用匿名内部类
  • 匿名内部类必须得要有父类,或者是实现了接口

一般使用匿名内部类的场景是,要继承或实现的接口只有一个抽象方法,比如添加一个监听器:


返回顶层目录

实例一
public class Test {
	public void click() {
		// 匿名内部类,实现的是ActionListener接口
		new ActionListener() {
			public void onAction() {
				System.out.println("click action...");
			}
		}.onAction();
	}

	// 匿名内部类必须继承或实现一个已有的接口
	public interface ActionListener {
		public void onAction();
	}

	public static void main(String[] args) {
		Test button = new Test();
		button.click();
	}
}

示例二
abstract class Person {
	public abstract void eat();
}

class Child extends Person {
	public void eat() {
		System.out.println("eat something");
	}
}

public class Test {
	public static void main(String[] args) {
		Person p = new Child();
		p.eat();
	}
}

示例三
abstract class Person {
	public abstract void eat();
}

public class Test {
	public static void main(String[] args) {
		Person p = new Person() {
			public void eat() {
				System.out.println("eat something");
			}
		};
		p.eat();
	}
}

示例四
interface Person {
    public void eat();
}
 
public class Test {
    public static void main(String[] args) {
        Person p = new Person() {
            public void eat() {
                System.out.println("eat something");
            }
        };
        p.eat();
    }
}

示例五

public class Test {
    public static void main(String[] args) {
        Thread t = new Thread() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        t.start();
    }
}

示例六
public class Test {
    public static void main(String[] args) {
        Runnable r = new Runnable() {
            public void run() {
                for (int i = 1; i <= 5; i++) {
                    System.out.print(i + " ");
                }
            }
        };
        Thread t = new Thread(r);
        t.start();
    }
}
返回顶层目录

看到这里,如果感兴趣的话,加微cr13219748239,白嫖全栈学习资料资料。


返回目录

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值