Java学习笔记(疯狂Java讲义第三版)——局部内部类、匿名内部类

局部内部类:

如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类。其作用域仅在这个方法内部有效,无法在方法外部使用。关于这一点可以近似的理解为相当于在方法中定义了一个普通变量,只能在该方法中使用。

所以有关局部内部类的使用:1、定义变量。2、创建对象。3、被子类继承也只能在该方法的内部使用。所以在方法内部使用起来和一个普通类的使用规则几乎一样。

局部内部类是一个非常"鸡肋"的语法,在实际开发中很少定义局部内部类,这是因为局部内部类的作用域太小了:只能在当前方法中使用。大部分时候定义一个类之后,当然希望多次重复使用这个类,但局部内部类无法离开它所在的方法,因此实际开发中很少使用局部内部类。(书中原文)

匿名内部类

什么是匿名内部类?
定义一个类的同时会立即创建一个该类的实例,这个定义完成的类会立即消失,进而无法重复使用,这个类也没有名字,且在定义时候一定是在一个类的内部中定义的,故称为匿名内部类。

什么样的类能称为匿名内部类。
匿名部类的用途针对的是如果一个类,创建完之后,只使用一次,创建一个对象之后,就不用了,那么这种类可以定义成匿名内部类。

先看一遍书中对于定义匿名内部类的语法介绍。
new 实现接口() | 父类构造器(实参列表)
{
//匿名内部类的类体部分。
}
通过上述内容,可以定义匿名内部类有两种定义的形式:
1、
new 实现接口()
{

}

2、
new 父类构造器(实参列表)
{

}

匿名内部类只能实现一个接口,或者只能继承一个父类。二者二选一

我先看下匿名内部类的使用,最常用的是第一种形式。new 实现接口(){}

interface A
{
int a;
}

class B
{
public static void main(String[] args){
A a = new A(){};
}
}
上述代码new A(){}就是一个匿名内部类,该类继承了接口A。等价于
class C implements A
{

}

个人理解:Java的编程主要就是通过定义类然后创建对象进而实现编程的目的。
我们细数下定义类及创建对象的几种形式
1、定义一个类,不显示继承任何符合和实现任何接口。——创建对象
2、定义一个类,继承一个父类、不实现任何接口。——创建对象。
3、定义一个类、继承一个父类、实现一个或多个接口。——创建对象
4、定义一个类、不显示继承任何父类、实现一个接口。——创建对象
5、定义一个类、不显示继承任何父类、实现多个接口。——创建对象。

匿名内部类在使用的时候,定义的这个匿名必须且只能实现一个类或实现一个接口。也就是上述:
定义一个类、实现一个接口
定义一个类、继承一个父类
这两种情况可以即通过定义一个类,然后通过这个类来创建对象。也可以通过匿名内部类的形式来创建对象。如果这个类只需要使用一次,那么匿名内部类无论是从语法是还是内存空间占用上都是更加良好的选择。

关于匿名内部类,其本身肯定不会是一个抽象类,因为匿名内部类在定义的时候就会创建对象而抽象类是不能创建对象的。

匿名内部类不能定义构造器,因为匿名内部类没有类名,构造器的名字需要和类名一样。(书中解释)
也不能有类成员(因为定义一次类就消失了,所以没有意义),但是可以有普通成员。
个人理解。

当匿名内部类是实现的某一个接口的时候,使用的的语法为:
new 实现接口名(){}//由于接口中没有构造器,且内部类中也不能·人为的定义构造器,所以可以近似的理解调用了一个由系统提供的一个无参构造器。

当匿名内部类继承的是某一个类的时候,匿名内部类将拥有和父类相似的构造器。特别指出是和父类相似的构造器,这里的相似指的是有和父类构造器一样的形参列表。例如:
class A
{
int a;
int b;
public A(int a, int b){
this.a = a;
this.b = b;
}
}

class Test
{
public static void main(String[] args)
{
A a = new A(2 ,3){};//拥有和父类相似的构造器
}
}
对于一个构造器来说,其名字和类名是一样的,但是匿名内部类没有类名,所以对于继承了一个父类的匿名内部类来说只是拥有和父类相似的构造器,即参数列表相同。

如果匿名内部类实现的是一个拥有抽象方法的接口或者是一个拥有抽象方法的抽象类,则必须要实现其抽象方法。

当然,匿名内部类也可以重写父类或者实现接口中的方法。

特别强调,被局部内部类或匿名内部类访问的局部变量,必须用final关键字修饰。如果不写则系统也会自动添加。例如:
public void info()
{
A a = new A(2, 3){};//注意此时a变量等价于final A a = new A(2, 3);
}所以,也不能在对a变量进行二次赋值了

这是Java 8才有的,Java 8之前a变量必须定义成final A a = new A(2, 3){}:
Java 8将这个功能称为effectively final,它的意思是对于被内名内部类访问的局部变量,可以用final修饰,也可以不用final修饰,但必须按照有final修饰的方式来使用——也就是一次赋值后,以后不能重新赋值。(书中原文)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值