内部类是指在一个外部类的内部再定义一个类。
内部类的作用:
1). 内部类可以很好的实现隐藏,也就是封装性。一般的非内部类,是不允许有 private 与protected权限的,但内部类可以
2). 内部类可以直接访问外部类的所有属性和方法,即使是private修饰的
3). 可以实现多重继承
4). 可以不修改接口而实现同一个类中有两个同名方法
一、成员内部类(外部类的成员变量)
说明:编译之后,内部类字节码文件是:Outer$Inner.class
1)内部类可以直接访问外部类中的私有属性。实际上内部类已经破坏了一个类的基本结构,因为类是由属性及方法组成的,这是内部类的缺点;内部类可以直接访问外部类中的私有属性,这是其最大的优点
package com.wbf.test1; class Outer{ private String info = "hello world!!!";//外部类的私有属性 class Inner{ public void print(){ System.out.println(info);//直接访问外部类的私有属性 } }; public void fun(){ new Inner().print();//内部类的实例化对象调用自身的方法 } }; public class InnerClassDemo01 { public static void main(String[] args) { Outer outer = new Outer(); outer.fun(); } }
2)一个内部类除了可以通过外部类访问,也可以直接在其他类中进行调用
package com.wbf.test3; class Outer{ private String info = "hello world!!!";//外部类的私有属性 class Inner{ public void print(){ System.out.println(info);//直接访问外部类的私有属性 } }; }; public class InnerClassDemo03 { public static void main(String[] args) { /* Outer.Inner in = new Outer.Inner();//error, No enclosing instance of type Outer is accessible, 必须先有Outer类的实例 in.print(); */ Outer out = new Outer(); Outer.Inner in = out.new Inner(); in.print(); } }
一个内部类除了可以通过外部类访问,也可以直接在其他类中进行调用
格式:外部类.内部类 内部类对象 = 外部类实例.new 内部类();
以上的格式中,首先要找到外部类的实例化对象之后,才可以通过外部类的实例化对象去实例化内部类的对象
注意:此时的Inner类非static
如果Inner类用static修饰,那么在类加载的之后,对于Outer类来说,即使没有Outer类的实例化对象,Inner这个成员变量已经存在
反之,Inner类没有用static修饰,那么在没有Outer类实例化对象的情况下,对于Outer类来说,Inner这个成员变量根本就不存在,此时要直接实例化Inner,肯定是不行的
所以在一般情况下,当先有外部类的实例化对象之后,再通过外部类的对象去实例化内部类
三、静态内部类(用static声明内部类)
说明:静态内部类和普通的内部类一个区别:普通内部类不能有static方法和static属性,也不能包含静态内部类,但静态内部类可以。而静态内部类不能声明为private,一般声明为public,方便调用。编译之后,内部类字节码文件是:Outer$Inner.class
package com.wbf.test2; class Outer{ private static String info = "hello world!!!";//外部类的私有属性 static class Inner{ public void print(){ System.out.println(info);//直接访问外部类的私有属性,同时这里info属性用static修饰 } }; }; public class InnerClassDemo02 { public static void main(String[] args) { new Outer.Inner().print();//通过new Outer.Inner()来实例化内部类,同时调用内部类的方法 /* Outer.Inner in = new Outer.Inner(); in.print(); */ } }
static可以声明属性或方法,而是用static也可以声明内部类
用static声明的内部类成为外部类,但是用static声明的内部类不能访问外部类的非static属性
四、局部内部类(在方法中定义内部类)
说明:编译之后,内部类字节码文件是:Outer$1Inner.class
package com.wbf.test4; class Outer{ private String info = "hello world!!!";//外部类的私有属性 public void fun(final int temp){ class Inner{ public void print(){ System.out.println("方法中的参数: " + temp);//访问方法中的final参数 System.out.println("类中的属性: " + info);//直接访问外部类的私有属性 } }; new Inner().print(); } }; public class InnerClassDemo04 { public static void main(String[] args) { Outer outer = new Outer(); outer.fun(20); } }
可以在一个方法中定义一个内部类,但是在方法中定义的内部类不能够直接访问方法中的参数;如果方法中的参数要想被内部类所访问,则参数前必须加上final关键字
五、匿名内部类
说明:编译之后,内部类字节码文件是:X$1.class
1)未使用匿名内部类
package com.wbf.test5; interface A { public void printInfo(); } class B implements A { public void printInfo(){ System.out.println("hello world!!!"); } } class X { public void fun1(){ this.fun2(new B()); } public void fun2(A a){ a.printInfo(); } } public class AnonymousInnerClassDemo { public static void main(String[] args) { new X().fun1(); } }
但是现在如果接口的实现类B只使用一次,那么还有必要单独定义一个子类B吗?很明显没有必要,所以此时就要使用匿名内部类完成
2)使用匿名内部类
package com.wbf.test6; interface A { public void printInfo(); } class X { public void fun1(){ this.fun2(new A(){//匿名内部类 public void printInfo(){//实现接口中的抽象方法 System.out.println("hello world!!!"); } }); } public void fun2(A a){ a.printInfo(); } } public class AnonymousInnerClassDemo { public static void main(String[] args) { new X().fun1(); } }
六、Java通过内部类变相实现多重继承
package com.wbf.test7; abstract class Father{ public abstract void run(); }; abstract class Mother{ public abstract void say(); }; class Son extends Father{ public void run(){ System.out.println("running..."); } Mother getMother(){ return new Mother(){ public void say(){ System.out.println("saying..."); } }; } }; public class DuplicateExtendsDemo { public static void main(String[] args) { Son s = new Son(); s.run(); s.getMother().say(); } }
相关推荐
Java SE(Standard Edition)是Java的一个重要版本,它包含了大量的常用类,这些类是Java开发中经常用到的基础工具和组件。在本系列文档中,我们将深入学习Java常用类的使用和原理,这些知识对于掌握Java高级特性至...
Java多线程编程是JavaSE(Standard Edition)核心技术之一,被广泛应用于复杂应用系统的设计中,以实现高效的并发处理。 首先,我们要理解什么是线程。线程,也可以理解为进程内部的执行路径,是程序中最小的执行...
【JavaSE:方法详解】 Java方法是编程中的一个重要概念,它是执行特定任务的代码段的集合,具有封装和重用的特性。在Java中,方法主要用于实现特定功能,提高代码的可读性和可维护性。 1. **方法的定义** - **...
Java集合框架是JavaSE标准库中的一个重要组成部分,它为Java程序员提供了一系列接口和类来管理对象集合。集合框架的设计使得程序员在处理数据集合时可以更加高效和方便,无论是在空间的利用还是数据的存取方面。 ...
在方法体内部,可以使用return语句返回计算结果或结束方法执行。如果方法声明为void,则不需要return语句。需要注意的是,在Java中方法的命名通常遵循驼峰命名法,首单词小写,后续单词首字母大写。 关于方法调用,...
另外,IP地址还分为公网地址和私有地址,公网地址用于互联网,而私有地址通常用于局域网内部通信。例如,192.168.开头的地址就是私有地址。 端口号是网络通信中用于区分不同服务的编号,每个运行中的网络服务都需要...
异常链不仅可以用于内部异常的记录,也可以在抛出新的异常时提供原始异常的详细信息,便于开发者诊断和处理异常。 总体而言,Java的异常处理机制为开发高质量、高可靠性的软件提供了基础支持,允许开发者预见并处理...
- **内部类**:了解匿名、成员、局部和静态内部类,以及它们的使用场景。 通过深入学习这些JavaSE的基础知识,开发者将能够熟练地编写Java程序,为更高级的JavaEE和Android开发打下坚实的基础。在实际操作中,结合...
二维码(QR Code)是一种二维条码技术,广泛应用于信息传递、数据存储等领域。在Java编程环境中,如果需要生成或解析二维码,通常会依赖...同时,了解和熟悉这些库的内部原理,可以帮助优化二维码生成和识别的效率。
封装让数据和方法结合在一起,保护内部状态不受外部干扰。继承允许创建新的类,这些类可以获取已有类的特性,并对其进行扩展或修改。多态则增强了代码的灵活性,允许不同类型的对象对同一消息作出响应。 "错误处理...
本项目针对JavaSE的多个核心知识点进行了综合性的测试,涵盖了线程、集合、内部类、设计模式、枚举、IO流以及自定义注解等多个关键领域。 1. **线程**:在Java中,线程是程序执行的最小单位,通过`Thread`类或者...
public成员可以在任何地方访问,protected成员可以在同一包内或子类中访问,默认(包级私有)的成员只在同包内可见,而private成员只能在定义它的类内部访问。访问控制权限的设计有助于保护类的内部实现,防止不适当...
- **接口与内部类**:接口的定义与实现,静态与非静态内部类,匿名内部类的应用。 - **文件操作**:学习如何读写文件,使用File类进行目录管理,以及IO流的基本操作。 - **多线程**:线程的创建与管理,...
### JavaSE内部学习笔记知识点概览 #### 一、Java语言概述 - **1.1 基础常识** - **软件分类**:软件分为系统软件和应用软件两大类。系统软件支持计算机硬件正常工作,包括操作系统、设备驱动程序等;应用软件则...
- **对象(Object)**:类的一个实例,具有特定的状态和行为。 - **方法(Method)**:执行特定任务的过程或函数。 - **变量(Variable)**:存储数据值的容器。 - **包(Package)**:用于组织类和接口的命名空间。 - **...
1. 类与对象:类是创建对象的模板,对象是类的具体实例。 2. 创建类与对象:学习如何声明和实例化对象。 3. 引用类型:除了基本类型外,Java中的所有类型都是引用类型。 4. 内存管理:JVM通过堆、栈和方法区来管理...
- **静态初始化块**:类加载时执行一次。 ##### 3.10 封装 封装是指将数据和操作数据的方法组织在一起,并对外部隐藏实现细节。 - **实现方式**:使用private修饰符、getter/setter方法等。 ##### 3.11 继承 ...
`private`的成员只能在定义它的类内部访问。这种访问控制机制有助于保护数据的安全性,防止不必要的外部访问,同时保持良好的封装性。 通过理解并熟练运用这些JavaSE基础知识,开发者能够构建出结构清晰、易于维护...
javase,内部类,思维导图
同时,可以使用匿名内部类创建自定义的比较器来定制排序规则。 总结来说,"黑马程序员Javase笔记"涵盖了Java的基础语法、内存管理、面向对象编程、集合框架以及泛型和Map等内容,这些都是成为一名合格Java开发者...