一、内部类定义

  内部类(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. JavaScript 中的window.event代表的是事件的状态,jquery事件对象属性,jquery中如何使用event.target

    http://wenda.haosou.com/q/1373868839069215 http://kylines.iteye.com/blog/1660236 http://www.cnblogs. ...

  2. Python 特殊语法:filter、map、reduce、lambda

    Python内置了一些特殊函数,这些函数很具python特性.可以让代码更加简洁. 可以看例子: 1 filter(function, sequence): str = ['a', 'b','c', ...

  3. IntelliJ 2016.02设置maven 阿里云加速

    修改maven 的setting.xml <mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf ...

  4. remove() 方法的兼容问题

    一直以为jq的remove()方法是兼容的,今天才发现,原来ie的写法不一样,特作此记录. removeNode方法的功能是删除一个节点,语法为node.removeNode(false)或者node ...

  5. JSONP理解和使用

    一.代码使用: $.ajax({ async:false, url: http://跨域的dns, type: "GET", dataType: 'jsonp'}); 二.理解: ...

  6. POJ2411

    题目大意:一个宽w高为h的棋盘,现在要用1*2的多米诺骨牌不重叠地覆盖整个棋盘,问有多少种方案. h<11,w<11 分析:1.h*w若为奇数,则无解. 2.按行处理.处理第i行时,保证前 ...

  7. Spring-RMI固定端口

    Spring-RMI固定端口 最近接到一个需求项目所应用的RMI端口(数据传输端口)为随机指定的,项目要求对其端口固定,费劲周折找了很多资料,最后解决了问题.   其实解决问题的方法及其简单,只需要在 ...

  8. LayoutInflater.java (android-19)

    /* * Copyright (C) 2007 The Android Open Source Project * * Licensed under the Apache License, Versi ...

  9. 【php】assert函数的用法

    [php]assert函数的用法 http://www.douban.com/note/217557007/ 2012-06-01 10:32:37   assert这个函数在php语言中是用来判断一 ...

  10. Blackfin DSP(七):用SPORT口模拟SPI

    1.问题的提出 当系统从SPI device启动时,若SCLK = 133M,则SPI的最大速度为33M.然而,有一些串行的flash设备能更快的运行,因此,如果我们使用SPORT口,它的最大速度为S ...