Java笔记:内部类
1.把一个类放在另一类内部定义,这个定义在其他类里面的类就叫做内部类,包含内部类的类叫做外部类。内部类成员可以直接访问外部类的私有数据,但是外部类不能访问内部类的实现细节。
2.非静态内部类(没有static修饰的内部类)
package cn.lsl;
public class Cow {
private double weight;
public Cow(){}
public Cow(double weight){
this.weight = weight;
}
private class CowLeg{
private double length;
private String color;
public CowLeg(double length, String color) {
super();
this.length = length;
this.color = color;
}
public double getLength() {
return length;
}
public void setLength(double length) {
this.length = length;
}
public String getColor() {
return color;
}
public void setColor(String color) {
this.color = color;
}
public void info(){
System.out.println("颜色:" + color + ",高:" + length);
System.out.println("重:" + weight);
}
}
public void test(){
CowLeg cl = new CowLeg(2, "红色");
cl.info();
}
public static void main(String[] args) {
Cow cow = new Cow(123);
cow.test();
}
}
System.out.println("重:" + weight);这句代码在非静态内部类里可以直接访问外部类的private成员。
当调用非静态内部类的实例方法时,必须有一个静态内部类实例,而非静态内部类实例必须寄存在外部类实例里。
3.如果在外部类、内部类、内部类里方法里面出现了同名的变量,则可以通过this、外部类类名.this来访问
package cn.lsl;
public class Variable {
private String a = "外部类实例变量";
private class In{
private String a = "内部类实例变量";
public void info(){
String a = "局部变量";
System.out.println("外部类:" + Variable.this.a);
System.out.println("内部类:" + this.a);
System.out.println("局部变量:" + a);
}
}
public void test(){
In in = new In();
in.info();
}
public static void main(String[] args) {
new Variable().test();
}
}
三种访问形式:
System.out.println("外部类:" + Variable.this.a);
System.out.println("内部类:" + this.a);
System.out.println("局部变量:" + a);
4.外部类不能直接访问非静态内部类的实例Field,如果外部类需要访问非静态内部类的成员,则必须显示创建非静态内部类对象来调用访问其实例成员。
package cn.lsl;
public class Outer {
private int a = 5;
class In{
private int b = 23;
public void accessOuter(){
System.out.println("直接访问外部类的a的值" + a);
}
}
public void accessIn(){
//System.out.println("内部类b的值:" + b); 编译出错,不能直接访问
System.out.println("内部类b的值:" + new In().b);
}
public static void main(String[] args) {
Outer out = new Outer();
out.accessIn();
}
}
非静态内部类对象必须寄存在外部类对象里面,而外部类对象不一定要有非静态内部类对象寄存其中。即,如果存在一个非静态内部类对象,一定要存在一个被它寄存的外部类对象。
5.静态内部类(使用static修饰的内部类)
(1)如果使用static修饰一个内部类,则这个内部类就属于外部类本身,不属于外部类的某个对象。
(2)静态内部类可以包含静态成员,也可以包含非静态成员。根据静态成员不能访问非静态成员的规则,静态内部类不能访问外部类的实例成员,只能访问外部类的类成员。即使是静态内部类的实例方法也不能访问外部类的实例成员,只能访问外部类的静态成员。
package cn.lsl;
public class StaticIn{
private int a = 5;
private static int b = 23;
static class In{
private static int age;
public void accessOut(){
//System.out.println(a); //编译出错
System.out.println(b);
}
}
}
(3)外部类依然不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员
package cn.lsl;
public class StaticIn{
static class In{
private static int a = 5;
private int b = 23;
}
public void accessIn(){
// System.out.println(a); //编译出错
System.out.println(In.a);
// System.out.println(b); //编译出错
System.out.println(new In().b);
}
}
6.在外部类以外使用非静态内部类
如果希望在外部类以外的地方访问内部类,则内部类不能使用private访问控制权限,private修饰的内部类只能在外部类内部使用。
非静态内部类的对象必须寄存在外部类的对象里,因此创建非静态内部类之前,必须先创建其外部类对象。
eg:
package cn.lsl; class Out {
class In{
public In(String msg){
System.out.println(msg);
}
}
} public class CreateIn{
public static void main(String[] args) {
Out.In in = new Out().new In("测试信息");
}
}
在外部类以外的地方创建非静态内部类实例必须使用外部类实例和new来调用非静态内部类的构造器。
7.在外部类以外使用静态内部类
因为静态内部类是外部类类相关的,因此创建内部类对象时无须创建外部类对象。
package cn.lsl;
class StaticOut{
static class In{
public In(){
System.out.println("静态内部类的构造器");
}
}
}
public class CreateStaticOut {
public static void main(String[] args) {
StaticOut.In in = new StaticOut.In();
}
}
静态内部类和非静态内部类声明变量的语法是一样的,区别在于创建内部类对象时,静态内部类只需使用外部类即可调用构造器,而非静态内部类必须使用外部类对象来调用构造器。
8.局部内部类
如果把一个内部类放在方法里定义,则这个内部类就是一个局部内部类,局部内部类仅在该方法里有效。
由于局部内部类不能再方法以外的地方使用,因此局部内部类也不能使用访问控制符和static修饰符修饰。
如果需要用局部内部类定义变量,创建实例或派生子类,那么都只能在局部内部类所在的方法内进行。
package cn.lsl;
public class LocalIn {
public static void main(String[] args) {
class InnerBase{
int a;
}
class InnerSub extends InnerBase{
int b;
}
InnerSub is = new InnerSub();
is.a = 5;
is.b = 8;
System.out.println(is.a + "," + is.b);
}
}
9.匿名内部类
(1)匿名内部类适合创建那种只需要一次使用的类,创建匿名内部类时会立即创建一个该类的实例,这个类定义即消失,匿名内部类不能重复使用。
(2)匿名内部类的格式
new 父类构造器(实参列表)|实现接口(){
}
(3)匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口。
(4)匿名内部类不能是抽象类。
(5)匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器。但匿名内部类可以定义实例初始化块,通过实例初始化块来完成构造器需要完成的事情。
package cn.it.lsl;
interface Product{
public double getPrice();
public String getName();
}
public class AnonymousTest{
public void test(Product p){
System.out.println("购买" + p.getName() + ",花掉了" + p.getPrice());
}
public static void main(String[] args) {
AnonymousTest ta = new AnonymousTest();
ta.test(new Product(){
@Override
public double getPrice() {
// TODO Auto-generated method stub
return 190;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return "声卡";
}
});
}
}
test()方法需要传入一个Product对象作为参数,但Product只是一个接口,因此此处考虑创建一个Product接口实现类的对象传入该方法。
上面匿名内部类部分也可以等价于下面这段代码
public class AnonymousTest implements Product{
@Override
public double getPrice() {
// TODO Auto-generated method stub
return 100;
}
@Override
public String getName() {
// TODO Auto-generated method stub
return "声卡";
}
public void test(Product p){
System.out.println("购买" + p.getName() + ",花掉了" + p.getPrice());
}
public static void main(String[] args) {
AnonymousTest ta = new AnonymousTest();
ta.test(new AnonymousTest());
}
}
10.如果通过继承父类来创建匿名内部类,匿名内部类将拥有和父类相似的构造器,此处的相似指的是拥有相同的形参列表。
package cn.it.lsl;
abstract class Device{
private String name;
public abstract double getPrice();
public Device(){}
public Device(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class AnonymousInner {
public void test(Device d){
System.out.println("购买一个" + d.getName() + ",花掉了" + d.getPrice());
} public static void main(String[] args) {
AnonymousInner ai = new AnonymousInner();
ai.test(new Device("鼠标"){ @Override
public double getPrice() {
// TODO Auto-generated method stub
return 23;
}
});
Device d = new Device() {
{
System.out.println("匿名内部类初始化块");
} @Override
public double getPrice() {
// TODO Auto-generated method stub
return 32;
} //重写父类的实例方法
public String getName(){
return "键盘";
}
};
ai.test(d);
}
}
当创建匿名内部类时,必须实现接口或抽象父类里的所有抽象方法。如果有需要,也可以重写父类中的普通方法。
11.如果匿名内部类需要访问外部类的局部变量,则必须使用final修饰符来修饰外部类的局部变量
package cn.it.lsl;
interface A{
void test();
}
public class ATest {
public static void main(String[] args) {
//int age = 0;
final int age = 0;
A a = new A(){ @Override
public void test() {
System.out.println(age); } };
}
}
Java笔记:内部类的更多相关文章
- java 笔记(2) —— 内部类的作用
一.内部类简介 个人觉得内部类没多少研究价值,GUI中的事件响应算是非常典型的应用了. Java内部类其实在J2EE编程中使用较少,不过在窗口应用编程中特别常见,主要用来事件的处理.其实,做非GUI编 ...
- Thinking in Java 笔记
大二就买了这本书,如今再看这本书,看到了一些以前没看的细节,也有了不同的体会.本文使用第4版,整理每章的笔记心得.老外的书有个特点,他会花费大量的文字去阐述一个概念,这比堆代码强多了. 第 1 章 对 ...
- java笔记整理
Java 笔记整理 包含内容 Unix Java 基础, 数据库(Oracle jdbc Hibernate pl/sql), web, JSP, Struts, Ajax Spring, E ...
- Effective Java笔记一 创建和销毁对象
Effective Java笔记一 创建和销毁对象 第1条 考虑用静态工厂方法代替构造器 第2条 遇到多个构造器参数时要考虑用构建器 第3条 用私有构造器或者枚举类型强化Singleton属性 第4条 ...
- Java学习--内部类(一)
Java学习--内部类(一) 一. 内部类的定义和特点 class Outer{ privite int num = 5; class Inner{ public void Display(){ Sy ...
- Java的内部类
Java的内部类 首先我们来了解一下什么是内部类? 内部类是指在一个外部类的内部再定义一个类.内部类可以是静态static的,也可用public,default,protected和private修饰 ...
- java笔记00-目录
--2013年7月26日17:49:59 学习java已久,趁最近有空,写一个总结: java笔记01-反射:
- java使用内部类的好处及其初始化
java使用内部类的原因 每个内部类都能独立地继承自一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响 java内部类初始化 ForeCatal ...
- JAVA基础——内部类详解
JAVA内部类详解 在我的另一篇java三大特性的封装中讲到java内部类的简单概要,这里将详细深入了解java内部类的使用和应用. 我们知道内部类可分为以下几种: 成员内部类 静态内部类 方法内部类 ...
- JAVA面向对象-----内部类的概述
JAVA面向对象-–内部类的概述s 将类定义在另一个类的内部则成为内部类.其实就是类定义的位置发生了变化. 在一个类中,定义在类中的叫成员变量,定义在函数中的叫成员函数,那么根据类定义的位置也可以分为 ...
随机推荐
- Jquery()核心函数的7个重载方法
(1) jquery() 该函数返回一个空的jQuery对象.在jQuery1.4以后的版本中,改函数返回一个空的jQuery对象.在之后的版本中,该函数会返回一个包含document节点的对象. ( ...
- Android_开发人员经常使用的颜色
Android开发中经常要用一些个性化的颜色,然而茫茫的RBG颜色对比表,往往给人眼花缭乱的感觉,更别说从中轻易选出一两种比較惬意的颜色,以下我就总结一下开发中经常使用到的比較绚丽的颜色. 以下是经常 ...
- 用HMM(隐马)图解三国杀的于吉“质疑”
·背景 最近乘闲暇之余初探了HMM(隐马尔科夫模型),觉得还有点意思,但是网上的教程都超级枯草,可读性很差,抄来抄去的,一堆公式仍在你面前,谁能搞的懂(但园内的两篇写的还算不错.真才实学).在熬制3天 ...
- Exception dispatching input event. use XlistView
今天上午解决Bug,一个上午的时间: log: 11-01 14:49:14.826: E/InputEventReceiver(30810): Exception dispatching input ...
- Codeforces 437D The Child and Zoo(贪心+并查集)
题目链接:Codeforces 437D The Child and Zoo 题目大意:小孩子去參观动物园,动物园分非常多个区,每一个区有若干种动物,拥有的动物种数作为该区的权值.然后有m条路,每条路 ...
- 关于重写ID3 Algorithm Based On MapReduceV1/C++/Streaming的一些心得体会
心血来潮,同时想用C++连连手.面对如火如荼的MP,一阵念头闪过,如果把一些ML领域的玩意整合到MP里面是不是很有意思 确实很有意思,可惜mahout来高深,我也看不懂.干脆自动动手丰衣足食,加上自己 ...
- CloudNotes
CloudNotes 今天,我发布了CloudNotes的一个更新版本:1.0.5484.36793.这个版本与1.0.5472.20097不同的是,它拥有增强的笔记列表,与之前单调的列表系统相比,新 ...
- 十六进制颜色与Color对象的互相转换[C#]
原文:十六进制颜色与Color对象的互相转换[C#] C#十六进制颜色与Color对象的互相转换 把十六进制颜色转化为color对象ColorTranslator.FromHtml("#FF ...
- 快速构建Windows 8风格应用5-ListView数据控件
原文:快速构建Windows 8风格应用5-ListView数据控件 本篇博文主要介绍什么是ListView数据控件.如何构建ListView数据控件. 什么是ListView数据控件? 1) Li ...
- SQL点滴2—重温sql语句中的join操作
原文:SQL点滴2-重温sql语句中的join操作 1.join语句 Sql join语句用来合并两个或多个表中的记录.ANSI标准SQL语句中有四种JOIN:INNER,OUTER,LEFTER,R ...