黑马程序员——————> 局部内部类&匿名内部类

------- android培训、java培训、期待与您交流! ----------

如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。由于局部内部类不能在外部类的方法以外的地方使用,因此局部内部类也不能使用访问控制符和static修饰符修饰。

对于局部成员而言,不管是局部变量还是局部内部类,它们的上一级程序单元都是方法,而不是类,使用static修饰它们没有任何意义。因此,所有的局部成员都不能使用static修饰。不仅如此,因为局部成员的作用域是所在方法,其他程序单元永远也不可能访问另一个方法中的局部成员,所以所有的局部成员都不能使用访问控制符修饰。

 

如果需要用局部北部了定义变量,创建实例或派生子类,那么都只能在局部内部类所在的方法内进行。

 1 public class LocalInnerClass
 2 {
 3
 4     public static void main(String[] args)
 5     {
 6         //定义局部内部类
 7         class InnerBase
 8         {
 9             int a;
10         }
11         //定义局部内部类的子类
12         class InnerSub extends InnerBase
13         {
14             int b;
15         }
16         //创建局部内部类的对象
17         InnerSub is = new InnerSub();
18         is.a = 5;
19         is.b = 8;
20         System.out.println("InnerSub对象的a和b实例变量是:" + is.a + "," + is.b);
21
22     }
23
24 }

java8改进的匿名内部类

匿名内部类适合创建那种中需要一次使用的类,匿名内部类的语法有点奇怪,创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用,

定义匿名内部类的格式如下:

new 实现接口() | 父类构造器(实参列表)
{
      //匿名内部类的类体部分
}

可以看出,匿名内部类必须继承一个父类,或实现一个接口但最多只能继承一个父类,或实现一个接口。

关于匿名内部类还有如下两条规则:

1:匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类。

2:匿名内部类不能定义构造器。由于匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义初始化块,可以通过实例初始化块来完成构造器需要完成的事。

最常用的创建匿名内部类的方式是需要创建某个接口类型的对象,如下程序所示:

 1 interface Product
 2 {
 3     public double getPrice();
 4     public String getName();
 5 }
 6 public class AnonymousTest
 7 {
 8     public void test(Product p)
 9     {
10         System.out.println("购买了一个" + p.getName() + ", 花掉了" + p.getPrice());
11     }
12
13     public static void main(String[] args)
14     {
15         AnonymousTest ta = new AnonymousTest();
16         //调用test()时,需要传入一个Product参数
17         //此处传入匿名实现类的实例
18         ta.test(new Product()
19         {
20
21             @Override
22             public double getPrice()
23             {
24                 return 567.8;
25             }
26
27             @Override
28             public String getName()
29             {
30                 return "AGP显卡";
31             }
32         });
33     }
34 }

test()方法需要一个Product对象作为参数,但Product知识一个接口,无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法---如果这个Product接口实现类需要重复使用,则应该将该实现类定义成一个独立类;如果这个Product接口实现类只需使用一次,则可采用上面程序中的方式,定义一个匿名内部类。

定义匿名内部类无须class关键字,而是在定义匿名内部类时直接生成该匿名内部类的对象。

由于匿名内部类不能是抽象类,所以匿名内部类必须实现它的抽象父类或者接口里包含的所有抽象方法。

对于上面创建Product实现类对象的代码,可以拆分成如下代码。

 1 public class AnonymousTest implements Product
 2 {
 3
 4     @Override
 5     public double getPrice()
 6     {
 7         return 567.8;
 8     }
 9
10     @Override
11     public String getName()
12     {
13         return "AGP显卡";
14     }
15
16     public void test(Product p)
17     {
18         System.out.println("购买了一个" + p.getName() + ", 花掉了" + p.getPrice());
19     }
20
21     public static void main(String[] args)
22     {
23         AnonymousTest ta = new AnonymousTest();
24         //调用test()时,需要传入一个Product参数
25         ta.test(new AnonymousTest());
26     }
27 }

当通过实现接口来创建匿名内部类时,匿名内部类也不能显式创建构造器,因此匿名内部类只有一个隐式的无参数构造器,故new接口名后的扩号里不能传入参数值。

但如果通过继承父类来创建匿名内部类时,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的参数列表。

 1 abstract class Device
 2 {
 3     private String name;
 4     public abstract double getPrice();
 5     public Device(){}
 6     public Device(String name)
 7     {
 8         this.name = name;
 9     }
10
11     public String getName() {
12         return name;
13     }
14     public void setName(String name) {
15         this.name = name;
16     }
17
18 }
19 public class AnonymousInner
20 {
21     public void test(Device d)
22     {
23         System.out.println("购买了一个" + d.getName() + ", 花掉了" + d.getPrice());
24     }
25     public static void main(String[] args)
26     {
27         AnonymousInner ai = new AnonymousInner();
28 //        调用有参数的构造器创建Device匿名实现类的对象
29         ai.test(new Device("电饭煲")
30         {
31             @Override
32             public double getPrice()
33             {
34                 return 67.8;
35             }
36         });
37
38 //        调用无参数的构造器创建Device匿名实现类的对象
39         Device d = new Device()
40         {
41             //初始化块
42             {
43                 System.out.println("匿名内部类的初始化块");
44             }
45             //实现抽象方法
46             @Override
47             public double getPrice()
48             {
49                 return 56.2;
50             }
51             @Override
52             public String getName()
53             {
54                 return "键盘";
55             }
56         };
57         ai.test(d);
58     }
59 }

上面程序创建了一个抽象父类Device类,这个抽象父类里包含两个构造器:一个无参的,一个带参的。当创建以Device为父类的匿名对象时,即可以传入参数,代表调用父类带参的构造器;也可以不传入参数,代表调用父类无参构造器。

当创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法,如果有需要,也可以重写父类中的普通方法。

时间: 2024-12-28 01:43:14

黑马程序员——————> 局部内部类&匿名内部类的相关文章

黑马程序员_内部类与匿名内部类

??内部类分为普通内部类(有名)和匿名内部类.普通内部类分为成员内部类.局部内部类.静态内部类(嵌套内部类).顾名思义,内部类就是定义在一个类内部的类.什么时候都会使用内部类呢?当我们定义一个类,发现内部还有类时,比如我们定义人体body时,内部还有心.肝.皮.肺.肾,他们既属于body,又是一个独立的器官,这是为了更加方便的描述人体就会选择内部类来实现. 普通类 1.定义 讲一个类定义在另一个类的里面,对里面那个类就叫做内部类,或者嵌套类. 2.成员内部类 ????2.1形式: ???????

黑马程序员——面向对象--内部类

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 内部类: 内部类的访问规则: 1.内部类可以直接访问外部类中的成员,包括私有 之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式: 外部类名.this 2.外部类要访问内部类,必须建立内部类对象. class outer{ int num = 5; class inner{ System.out.println("num="+num);//可以直接调用外部成

黑马程序员——————> 使用内部类

------- android培训.java培训.期待与您交流! ---------- 定义类的主要作用就是定义变量,创建实例和作为父类被继承.定义内部类的主要作用也是如此,但使用内部类定义变量和创建实例则与外部类存在一些小小的差异.下面分三种情况讨论内部类的用法. 1:在外部类内部类使用内部类 在外部类内部使用内部类时,与平常使用普通类没太大区别.一样可以直接通过内部类类名来定义变量,通过new调用内部类构造器来创建实例. 唯一存在的区别是:不要在外部类的静态成员(包括静态方法和静态初始化块)

黑马程序员——java基础——内部类

 黑马程序员--java基础--内部类 ------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 内部类 如果A类需要直接访问B类中的成员,而B类又需要建立A类的对象.这时,为了方便设计和访问,直接将A类定义在B类中.就可以了.A类就称为内部类.内部类可以直接访问外部类中的成员.而外部类想要访问内部类,必须要建立内部类的对象. 内部类的访问规则 1,内部类可以直接访问外部类中的成员,包括私有. 之所以可以直接访问外部类中的成员,是因为内部类中持有

黑马程序员 内部类 Java

内部类:将一个类定义在另一个类里面,对里面那个类就叫做内部类(内置类,嵌套类). 访问特点:内部类可以直接访问外部类中的成员,包括私有成员.而外部类要访问内部类中的成员必须要建立内部类的对象. class Outer{ private int  x=3; class Inner{ void function(){ function1(); System.out.println("内部类"+x); } } void function1(){ System.out.println(&quo

黑马程序员_Java抽象类和内部类

- - - - - android培训.java培训.期待与您交流! - - - - - - 类(class) 类是相似对象中共同属性和方法的集合体 在面向对象中定义类,就是在描述事物,就是在定义属性(变量)和行为(方法).属性和行为共同成为类中的成员(成员变量和成员方法). 封装.继承和多态 面向对象方法中软件设计的主体是类,类是相同属性和方法的封装体,因此类具有封装性 子类可以在继承父类所有属性和方法的基础上,再增加自己特有的属性和方法,因此类具有继承性 在一个类层次中,定义为根类的对象可被

黑马程序员-内部类、 抽象类、接口

java面向对象中比较重要的知识还有内部类,抽象类.接口,这些和封装.继承.多态一起赋予java强大的面向对象的能力 1.抽象类 在面向对象的领域一切都是对象,同时所有的对象都是通过类来描述的,但是并不是所有的类都是来描述对象的.如果一个类没有足够的信息来描述一个具体的对象,而需要其他具体的类来支撑它,那么这样的类我们称它为抽象类. 创建抽象类和抽象方法非常有用,因为他们可以使类的抽象性明确起来,并告诉用户和编译器打算怎样使用他们.抽象类还是有用的重构器,因为它们使我们可以很容易地将公共方法沿着

黑马程序员—张老师基础加强7-动态代理

代理: 要为已经存在的多个具有相同接口的目标类的各个方法增加一些系统功能. 例如:异常处理,日志和计算方法的运行时间,事物管理等,怎么做 如 在运行前后增加计算时间的方法.show(){ sop(); } 编写一个与目标类具有相同接口的代理类,代理类的每个方法调用目标类的相同方法,并在调用方法时加上系统功能的代码. 动态代理: 要为系统中的各种接口的类增加代理功能,那需要太多代理类. jvm可以在运行期间动态生成出类的字节码,这种动态生成的类往往被调用作代理类, 即动态代理类. jvm生成动态类

黑马程序员_毕向东_Java基础视频教程_Java基础学习知识点总结

黑马程序员_毕向东_Java基础视频教程 Java基础学习知识点总结 2016年01月06日  day01 一.基础知识:软件开发 1.什么是软件?软件:一系列按照特定顺序组织的计算机数据和指令的集合. 2.常见的软件:系统软件:如:DOS,Windows,Linux等.应用软件:如:扫雷,迅雷,QQ等. 3.什么是开发?制作软件. 二.基础知识:人机交互方式 4.软件的出现实现了人与计算机之间的更好的交互. 5.交互方式:图形化界面:这种方式简单直观,使用者易于接受,容易上手操作.命令行方式: