一、内部类定义

  内部类(nested classes),面向对象程序设计中,可以在一个类的内部定义另一个类。嵌套类分为两种,即静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner)。内部类是JAVA语言的主要附加部分。内部类几乎可以处于一个类内部任何位置,可以与实例变量处于同一级,或处于方法之内,甚至是一个表达式的一部分。

  内部类是JAVA语言的主要附加部分。嵌套类从JDK1.1开始引入。其中inner类又可分为三种:
 
    其一、在一个类(外部类)中直接定义的内部类;
    其二、在一个方法(外部类的方法)中定义的内部类;
    其三、匿名内部类。

    

  为什么需要内部类?

    ⒈ 内部类对象可以访问创建它的对象的实现,包括私有数据;
    ⒉ 内部类不为同一包的其他类所见,具有很好的封装性;
    ⒊ 使用内部类可以很方便的编写事件驱动程序;
    ⒋ 匿名内部类可以方便的定义运行时回调
    5.内部类可以方便的定义

   每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。


二、内部类分类

  一、成员内部类

    作为外部类的一个成员存在,与外部类的属性、方法并列。

    成员内部类也是定义在另一个类中,但是定义时不用static修饰。

  成员内部类和静态内部类可以类比为非静态的成员变量和静态的成员变量。

  成员内部类就像一个实例变量。

  它可以访问它的外部类的所有成员变量和方法,不管是静态的还是非静态的都可以

  在外部类里面创建成员内部类的实例:

  this.new B();

  在外部类之外创建内部类的实例:

  (new Test1()).new B().go();

  在内部类里访问外部类的成员:

  Test1.this.member

  

 package memberiner;

 public class Test1 {
private String member="这是外部类变量";
//成员内部类
//不对外开放,高内聚
class B{
public B() {//当内部类的构造器为Protected、private修饰时外部类外不可以访问 }
public void go(){
System.out.println("这是内部类B的go方法"+Test1.this.member);//内部类访问外部类变量
}
} //可供成员的外部类中其他方法调用
public B show(){ return this.new B();//外部类调用 } public static void main(String[] args) { B b = new Test1().show();
} } package memberiner; public class A { public static void main(String[] args) { new Test1().show(); (new Test1()).new B().go();//外部类外访问内部类
} }

  

  二、方法内部类(局部内部类)

   定义在方法中,比方法的范围还小。是内部类中最少用到的一种类型。

  像局部变量一样,不能被public, protected, private和static修饰。

  只能访问方法中定义的final类型的局部变量。

  方法内部类在方法中定义,所以只能在方法中使用,即只能在方法当中生成方法内部类的实例并且调用其方法

  

 package methodinner;

 public class Test {

     class Duanzanshichangzheng {

         public  void noProblem() {
System.out.println("患有急性短暂失常症,开车撞死人没事"); } } private String member ="全局变量";
final int n=4;
public void driver(){
final String member2 ="局部变量";//方法内的变量只有final变量才能被方法内部类访问
System.out.println("我正在开车"+member); //每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,
//对于内部类都没有影响
//内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”
//短暂,不对外,防止变成全局
class B extends Duanzanshichangzheng {
public void show(){
System.out.println(member2+4);
}
}
new B().noProblem();//方法内部类里的方法只能在方法里调用
new B().show(); System.out.println("一切恢复正常"); } public static void main(String[] args) {
new Test().driver();
} }

  三、匿名内部类(Android运用最多)

    匿名内部类就是没有名字的局部内部类,不使用关键字class, extends, implements, 没有构造方法。

    什么情况下需要使用匿名内部类?如果满足下面的一些条件,使用匿名内部类是比较合适的:

      a·只用到类的一个实例。
      b·类在定义后马上用到。
      c·类非常小(SUN推荐是在4行代码以下)
      d·给类命名并不会导致你的代码更容易被理解。

    在使用匿名内部类时,要记住以下几个原则:

      a·匿名内部类不能有构造方法。
      b·匿名内部类不能定义任何静态成员、方法和类。
      c·匿名内部类不能是public,protected,private,static。
      d·只能创建匿名内部类的一个实例。
      e·一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
      f·因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。

  

以下是匿名内部类的实例:

  实例背景:输出每个Doctor博士每天做的事情

    1、白天大家都是“白天传授理论知识”;

    2、晚上每个人都是不一样的

  *用以前继承方法需要写多个实现类,而匿名内部类只需要实现“晚上做事workInNight()”这个方法就可以了

  代码目录

    

 package anonymousinner;

 public interface Qinshou {
public void workInNight();
}
 package anonymousinner;

 public abstract class Doctor implements Qinshou {
//多态,情况不定
public void workInDay(){
System.out.println("白天传授理论知识");
} }
 package anonymousinner;

 public class Doctor1 extends Doctor {

     public void workInNight(){
System.out.println("晚上教弹琴");
}
}
 package anonymousinner;

 public class Doctor2  extends Doctor{

     public void workInNight(){
System.out.println("晚上学习");
}
}
 package anonymousinner;

 public class Test {

     public static void main(String[] args) {
Doctor1 d1 = new Doctor1();
d1.workInDay();
d1.workInNight(); Doctor2 d2 = new Doctor2();
d2.workInDay();
d2.workInNight(); //语法格式
//1、new 抽象类或者接口
//2、后加大括号
//3、实现未实现方法
Doctor d3 = new Doctor(){ //匿名内部类
public void workInNight() {
System.out.println("睡觉");
} }; d3.workInDay();
d3.workInNight();
}
}

匿名内部类细节:

1、

 //
new Object(){
void show(){
System.out.println("show run");
}
}.show();//正确
//
Object obj = new Object(){
void show(){
System.out.println("show run");
}
};
obj.show();//编译错误
1和2的写法正确吗?有区别吗?说出原因。
写法是正确,1和2都是在通过匿名内部类建立一个Object类的子类对象。
区别:
第一个可是编译通过,并运行。
第二个编译失败,因为匿名内部类是一个子类对象,当用Object的obj引用指向时,就被提升为了
Object类型,而编译时检查Object类中是否有show方法,所以编译失败。 2、  
 class InnerClassDemo6 {
+(static)class Inner{
void show(){}
}
public void method(){
this.new Inner().show();//可以
}
public static void main(String[] args) {//static不允许this
This.new Inner().show();//错误,Inner类需要定义成static
}
}

还有很多的不懂,各位大神多多指教喔!

java基础:熟悉3种内部类的写法,重点匿名内部类的使用的更多相关文章

  1. java中的几种内部类

    Java中的几种内部类 内部类,听名字就可以知道是什么意思,就是类里面的类.有成员内部类,静态内部类,局部内部类和匿名内部类. 下面说一个每种内部类的的使用. 一.  成员内部类

  2. java基础(十三)-----详解内部类——Java高级开发必须懂的

    可以将一个类的定义放在另一个类的定义内部,这就是内部类. 为什么要使用内部类 为什么要使用内部类?在<Think in java>中有这样一句话:使用内部类最吸引人的原因是:每个内部类都能 ...

  3. 夯实Java基础(十一)——内部类

    1.内部类的概念 内部类顾名思义:将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.对于很多Java初学者来说,内部类学起来真的是一头雾水,根本理解不清楚是个什么东西,包括我自己(我太菜 ...

  4. Java中的四种内部类

    Java中有四种内部类: 成员内部类:定义在另一个类(外部类)的内部,而且与成员属性和方法平级,故称成员内部类.类比于外部类的非静态方法,如果用static修饰就变成了静态内部类 静态内部类:使用st ...

  5. java中的四种内部类使用(1)

    内部类 (一) 概述 把类定义在另一个类的内部,该类就被称为内部类. 举例:把类Inner定义在类Outer中,类Inner就被称为内部类. class Outer { class Inner { } ...

  6. JAVA基础之两种核心机制

    突然之间需要学习Java,学校里学的东西早就忘记了,得用最短的时间把Java知识理顺,重点还是J2EE,毕竟所有的ava项目中95%都是J2EE,还是先从基础的J2SE学起吧....... 首先是了解 ...

  7. (转)Java基础——嵌套类、内部类、匿名类

    本文内容分转自博客:http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内 ...

  8. java基础(5)内部类

    1 成员内部类的定义和使用 public class Outer { private String name; public class Inner { public void innerMethod ...

  9. Java 基础 面向对象之关键字内部类代码块修饰符

    final final概念 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后 ...

随机推荐

  1. (转)【重磅】无监督学习生成式对抗网络突破,OpenAI 5大项目落地

    [重磅]无监督学习生成式对抗网络突破,OpenAI 5大项目落地 [新智元导读]"生成对抗网络是切片面包发明以来最令人激动的事情!"LeCun前不久在Quroa答问时毫不加掩饰对生 ...

  2. lua加载动态库缺乏相应的系统库

    错误信息: 使用lua测试lm2动态库时,加载时出现如下错误 jfyuan@jfy11-B85M-D2V:~/temp/service/soft/code/ginger_resty/cores/lm2 ...

  3. Python学习笔记——Day1

    突破从改变开始,一行行字符,熟悉的感觉,还是那个味儿...呀哈哈哈 一.变量 变量是计算机语言中能存储计算结果或能表示值的抽象概念,变量可以通过变量名访问.调用及修改.变量通常表示可变状态,即具有存储 ...

  4. vb6 枚举对象属性

    Option Explicit '引用Library TLI ' C:\WINDOWS\system32\TLBINF32.DLL ' TypeLib Information Private Sub ...

  5. RabbitMQ、ActiveMQ和ZeroMQ

    消息中间件的技术选型心得-RabbitMQ.ActiveMQ和ZeroMQ 作者:chszs,转载需注明.博客主页:http://blog.csdn.net/chszs RabbitMQ.Active ...

  6. spring 3 mvc hello world + mavern +jetty

    Spring 3 MVC hello world example By mkyong | August 2, 2011 | Updated : June 15, 2015 In this tutori ...

  7. VS2012打开解决方案崩溃或点击项目崩溃

    打开项目文件就VS2012就崩溃 解决方案: 步骤1:开始-->所有程序-->Microsoft Visual Studio 2012-->Visual Studio Tools-- ...

  8. ASP.NET MVC利用ajax把action的JavaScript注册到页面并执行

    相信大家在做Webform时经常会遇到在页面的后台CS文件中根据数据运行结果修改页面显示样式.显示(隐藏).或者弹出框,当时我们会用到ScriptManage或者Page来向页面注册一段js来实现页面 ...

  9. Linux下删除空文件,删除指定大小的文件

    Linux下批量删除空文件(大小等于0的文件)的方法: find . -name "*" -type f -size 0c | xargs -n 1 rm -f 用这个还可以删除指 ...

  10. oracle控制文件丢失恢复

    在学习群里有个同学误删除了控制文件,于是我也把自己数据库的控制文件删除了,看看能不能进行恢复,以下是整个实验的过程~~在做之前,先看看控制文件的备份方式:1.生成可以重建控制文件的脚本.2.备份二进制 ...