java基础:熟悉3种内部类的写法,重点匿名内部类的使用
一、内部类定义
内部类(nested classes),面向对象程序设计中,可以在一个类的内部定义另一个类。嵌套类分为两种,即静态嵌套类和非静态嵌套类。静态嵌套类使用很少,最重要的是非静态嵌套类,也即是被称作为内部类(inner)。内部类是JAVA语言的主要附加部分。内部类几乎可以处于一个类内部任何位置,可以与实例变量处于同一级,或处于方法之内,甚至是一个表达式的一部分。
为什么需要内部类?
每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。如果没有内部类提供的可以继承多个具体的或抽象的类的能力,一些设计与编程问题就很难解决。从这个角度看,内部类使得多重继承的解决方案变得完整。接口解决了部分问题,而内部类有效地实现了“多重继承”。
二、内部类分类
一、成员内部类
作为外部类的一个成员存在,与外部类的属性、方法并列。
成员内部类也是定义在另一个类中,但是定义时不用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种内部类的写法,重点匿名内部类的使用的更多相关文章
- java中的几种内部类
Java中的几种内部类 内部类,听名字就可以知道是什么意思,就是类里面的类.有成员内部类,静态内部类,局部内部类和匿名内部类. 下面说一个每种内部类的的使用. 一. 成员内部类
- java基础(十三)-----详解内部类——Java高级开发必须懂的
可以将一个类的定义放在另一个类的定义内部,这就是内部类. 为什么要使用内部类 为什么要使用内部类?在<Think in java>中有这样一句话:使用内部类最吸引人的原因是:每个内部类都能 ...
- 夯实Java基础(十一)——内部类
1.内部类的概念 内部类顾名思义:将一个类定义在另一个类里面或者一个方法里面,这样的类称为内部类.对于很多Java初学者来说,内部类学起来真的是一头雾水,根本理解不清楚是个什么东西,包括我自己(我太菜 ...
- Java中的四种内部类
Java中有四种内部类: 成员内部类:定义在另一个类(外部类)的内部,而且与成员属性和方法平级,故称成员内部类.类比于外部类的非静态方法,如果用static修饰就变成了静态内部类 静态内部类:使用st ...
- java中的四种内部类使用(1)
内部类 (一) 概述 把类定义在另一个类的内部,该类就被称为内部类. 举例:把类Inner定义在类Outer中,类Inner就被称为内部类. class Outer { class Inner { } ...
- JAVA基础之两种核心机制
突然之间需要学习Java,学校里学的东西早就忘记了,得用最短的时间把Java知识理顺,重点还是J2EE,毕竟所有的ava项目中95%都是J2EE,还是先从基础的J2SE学起吧....... 首先是了解 ...
- (转)Java基础——嵌套类、内部类、匿名类
本文内容分转自博客:http://www.cnblogs.com/mengdd/archive/2013/02/08/2909307.html 将相关的类组织在一起,从而降低了命名空间的混乱. 一个内 ...
- java基础(5)内部类
1 成员内部类的定义和使用 public class Outer { private String name; public class Inner { public void innerMethod ...
- Java 基础 面向对象之关键字内部类代码块修饰符
final final概念 继承的出现提高了代码的复用性,并方便开发.但随之也有问题,有些类在描述完之后,不想被继承,或者有些类中的部分方法功能是固定的,不想让子类重写.可是当子类继承了这些特殊类之后 ...
随机推荐
- day17算法
http://www.360doc.com/content/14/0804/11/1073512_399302715.shtml
- javascript:void(0) ,设置a链接无效,设置点击a页面不刷新,不跳动
http://www.cnblogs.com/opper/archive/2009/01/12/1373971.html 我想使用过ajax的都常见这样的代码: <a href="ja ...
- input:-webkit-autofill 导致chrome的输入框背景颜色变成黄色
填写form表单时发现chrome的一个好坑啊! 当你之前有填写过表单,获取焦点时,input会有一个记录之前填写过的文本的下拉列表式的东东,就像这样:(抱歉丑了点,隐私问题打上了马赛克) 按理说,这 ...
- IDEA 中 显示 *.properties 为中文
效果:
- javascript事件类型之界面拖拽交互
一.在线DEMO 界面拖拽交互
- ssl_error_rx_record_too_long
Linux下安装SSL 当使用https访问时出现: SSL 接收到一个超出最大准许长度的记录. (错误码: ssl_error_rx_record_too_long) 网上说修改虚拟机 vi /et ...
- IOS中图片拉伸技巧与方法总结(转载)
以下内容转载自:http://my.oschina.net/u/2340880/blog/403996 IOS中图片拉伸技巧与方法总结 一.了解几个图像拉伸的函数和方法 1.直接拉伸法 简单暴力,却是 ...
- JavaScript中 Promise的学习以及使用
今天一个哥们发过来一段js代码,没看懂,就顺便学习了一下,代码如下 Promise.resolve('zhangkai').then(value => {console.log(value)} ...
- Datagridview 列绑定
Datagridview 列绑定 dataGridView1.Columns.Clear(); dataGridView1.Columns.Add("id", "id&q ...
- php 读取文件readfile
<?php //读取文件 //echo readfile('aa.txt'); //打开文件更好的方法是fopen $f = fopen('aa.txt' , 'r') or die('unab ...