咳咳咳!!!!!
博主真的是正儿八经的人,但是是不是正儿八经的讲就不知道了
目录:
1.成员内部类
1.成员内部类:
1.概念:
定义在类的内部,成员位置上的非静态类
例子:
package untl1;
public class outer {
private static int a = 1;
private int b = 2;
class inner {
public int c=3;
public void visit() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
public static void main(String[] args) {
}
}
2.关于成员内部类的主意点:
(3)静态内部类的创建(衔接上边的代码):1.成员内部类可以访问外部类的所有变量和方法,包括静态和非静态,私有和公有的
2.内部类和外部类是两个独立的类,运行时会各自生成自己的.class文件
3.内部类相当于外部类的一个成员变量,可以用public,private等修饰符修饰(平时正常的类只能被public或默认的default修饰)
4.成员内部类不能有静态方法属性和静态初始化块
5.内部类的实例化对象一定是绑定在外部类的实例上,存在外部类对象才有内部类对象(你总不能没媳妇就有儿子了吧)
6.要调用内部类的方法就必须通过实例的内部类对象
外部类名.内部类名 自定义内部类引用=外部类实例.new 内部类()
;
outer o=new outer();
outer.inner p=o.new inner();
p.visit();
2.局部内部类:
(2).概念:
定义在方法中的内部类,就是局部内部类
例子:
package untl1;
public class outer {
private static int a = 1;
private int b = 2;
public void visit()
{
int c = 3;
class inner {
public void visit() {
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
}
inner p1 = new inner();
p1.visit();
}
public static void main(String[] args)
{
int d = 4;
class inner {
private void fly() {
System.out.println(a);
// System.out.println(b); 带上就报错
System.out.println(d);
}
}
inner p1=new inner();
p1.fly();
}
}
(2)局部内部类的注意事项:
1.定义在实例方法中的局部内部类可以访问外部类所有变量和方法
2.定义在静态方法中的局部类只能访问外部类的静态变量和方法
3.方法内部类只能在方法内部使用
4.由于方法内部类只能在所在的方法内部使用所以不能用访问控制符和static修饰
5.匿名内部类访问局部变量的时候,必须声明为 final(最后会提)
(3)局部内部类的创建和正常类一样
public static void testStaticFunctionClass(){
class Inner {
}
Inner inner = new Inner();
}
3.匿名内部类:
1.概念:
匿名内部类就是没有名字的内部类,日常开发中使用的比较多
(2)使用匿名内部类的前提:
1.使用匿名内部类必须继承一个父类(可以是抽象类还可以是正常修饰符修饰的类)或者实现一个接口,但是最多只能继承一个父类或者一个接口)
2.匿名内部类没有构造器(连名字都没有哪来的构造器),
3.匿名内部类不是抽象类(创建一个匿名内部类的时候会立刻创建一个匿名内部类的对象,抽象类哪有实例化对象之说,而且抽象类是有构造器的)
(3)例子1(实现接口):
public class Outer {
private void test(final int i) {
new Service() {
public void method() {
for (int j = 0; j < i; j++) {
System.out.println("匿名内部类" );
}
}
}.method();
}
}
interface Service{
void method();
}
例子2(继承类):
package untl1;
abstract class A{
abstract void fly();
}
public class outer {
private static int a = 1;
private int b = 2;
public static void main(String[] args) {
A a= new A(){
private int b=2;
void fly()
{
System.out.println("我会单飞");
}
};
a.fly();
System.out.println(a.b);//加上会报错,因为创建的是一个A的对象所以每有b这个属性
}
}
想要得到b这个属性可以用下面的这个:
package untl1;
abstract class A{
abstract void fly();
}
public class outer {
private static int a = 1;
private int b = 2;
public static void main(String[] args) {
int c= new A(){
private int b=2;
void fly()
{
System.out.println("我会单飞");
}
}.b;
System.out.println(c);
}
}
(4)匿名内部类的注意事项:
1.匿名内部类不能定义任何静态成员和静态方法
2.匿名内部类访问局部变量的时候,必须声明为 final(最后会提)
3.只能创建一个实例
(5)匿名内部类创建方式:
new 类/接口{
//匿名内部类实现部分
}
4.静态内部类:
(1).概念:
定义在类内部的静态类就叫静态内部类
例子:
public class Outer {
private static int radius = 1;
static class StaticInner {
public void visit() {
System.out.println("visit outer static variable:" + radius);
}
}
}
(2)注意事项:
只能访问外部类所有的静态变量
(3)创建方法:
静态内部类名 对象名=new 静态内部类();
5.内部类的优点
我们为什么要使用内部类呢?因为它有以下优点:1.一个内部类对象可以访问创建它的外部类对象的内容,包括私有数据!
2.内部类不为同一包的其他类所见,具有很好的封装性;
3.内部类有效实现了“多重继承(并不是真的多重继承,而是由于它既能访问外部类的属性还能访问自己继承的类的属性,有着一类包含多类的效果)”,优化 java 单继承的缺陷。
4.匿名内部类可以很方便的定义回调。
6.内部类有哪些应用场景
1.一些多算法场合
2.解决一些非面向对象的语句块。
3.当某个类除了它的外部类,不再被其他的类使用时。
最后就是局部内部类和匿名内部类访问局部变量的时候,为什么变量必须要加上final?
先看这段代码:
public class Outer {
void outMethod(){
final int a =10;
class Inner {
void innerMethod(){
System.out.println(a);
}
}
}
}
以上例子,为什么要加final呢?
是因为生命周期不一致, 局部变量直接存储在栈中,当方法执行结束后,非final的局部变量就被销毁。而局部内部类对局部变量的引用依然存在(这里你创建的内部类还在堆空间里没被销毁所以引用还在),如果局部内部类要调用局部变量时,就会出错。加了final,可以确保局部内部类使用的变量与外层的局部变量区分开