Java基础—内部类
内部类
内部类的基本概念
在我之前的博客中给大家介绍了面向对象的核心组成结构:接口、抽象类、普通类,如果有不熟悉的或者什么问题可以参考我之前的博文: Java基础—抽象类与接口 这些结构都是允许进行嵌套的,所以才有了内部类的概念。
下面观察内部类的形式:
//定义一个外部类
class Outer{
...
//定义一个内部类
class Inner{
...
}
}
为什么要用内部类
内部类可以只针对外部类服务,将所需要的特定功能全部封装在一个类中,方便程序的管理。
内部类的分类
内部类共有四种:成员内部类、静态内部类、方法内部类、匿名内部类。
成员内部类
成员内部类,就是指把内部类放在外部类之中当做外部类中的一个成员来使用,内部类可以访问外部类中的所有方法、属性。外部类访问内部类的时候需要实例化内部类对象,形式如下:
外部类.内部类 内部类对象 = new 外部类().new 内部类();
//成员内部类
class Outer{
//定义外部类中的属性;
private String name = "zhangdapao";
//定义外部类中的方法;
public void send(String str){
System.out.println(str);
}
class Inner{
private String name = "123";
public void print(){
System.out.println(name);
//调用外部类的方法以及外部类中的属性;
send(Outer.this.name);
};
}
}
public class Test01{
public static void main(String[] args) {
//实例化内部类对象;
Outer.Inner inner = new Outer().new Inner();
//调用内部类的方法
inner.print();
}
}
执行结果为:D:\java\jdk-11\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2018.3.2\lib\idea_rt.jar=63909:D:\IDEA\IntelliJ IDEA 2018.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\JavaTest\out\production\Test01 zhang.da.pao.Test01
123
zhangdapao
Process finished with exit code 0
成员内部类有如下几点性质:
1.内部类可以使用外部类中的任意方法、属性,不需要考虑访问修饰符。
2.在内部类中,若内部类和外部类的属性或方法产生冲突:
· 调用外部类中的方法或属性:外部类.this.属性或方法名;
· 调用内部类中的方法或属性:属性或方法名;
3.内部类的内部不能有静态信息。
4.外部类想要访问内部类中的方法或者属性必须先进行内部类对象的实例化操作。
5.在其他类中想要访问一个外部类中的内部类:外部类.内部类 内部类对象 = new 外部类().new 内部类();
静态内部类
static关键字定义的属性和方法虽然是在类中定义的,但不收对象实例化的限制,如果在内部类上使用static来定义的话,表示该类变成了一个外部类,并且只能够访问外部类中的static操作。
//使用static定义内部类
class Message{
private static final String str = "zhangdapao";
static class InnerMessage{
public void print(){
//直接访问外部类的static属性
System.out.println(Message.str);
}
}
}
public class Test01{
public static void main(String[] args) {
Message.InnerMessage msg = new Message.InnerMessage();
msg.print();
}
}
执行结果为:D:\java\jdk-11\bin\java.exe "-javaagent:D:\IDEA\IntelliJ IDEA 2018.3.2\lib\idea_rt.jar=59123:D:\IDEA\IntelliJ IDEA 2018.3.2\bin" -Dfile.encoding=UTF-8 -classpath D:\JavaTest\out\production\Test01 zhang.da.pao.Test01
zhangdapao
Process finished with exit code 0
1.静态内部类不能直接访问外部类的非静态成员,但可以通过 new 外部类().成员 的方式访问
2.外部类的静态成员与内部类的成员名称相同,可通过“类名.静态成员”访问外部类的静态成员
3.创建静态内部类的对象时,不需要通过外部类的对象,可以直接创建 内部类 对象名= new 内部类();
方法内部类
方法中定义的内部类可以直接进行方法参数的访问,在JDK1.8之前操作时需要在参数前加上final关键字。示例代码如下:
//方法定义内部类,内部类直接使用方法中的参数
class Message{
public void send(String str){
class InnerMessage{
public void print(){
for(int x = 0;x<6;x++){
System.out.println(str);
}
}
}
InnerMessage msg = new InnerMessage();
msg.print();
}
}
public class Test01{
public static void main(String[] args) {
Message msg = new Message();
msg.send("zhangdapao");
}
}
小结:
1.在类的方法中定义,只能在同一个作用域使用,不存在外部可见性
2.没有访问修饰符,但可以使用final 或 abstract修饰。
3.不能在方法内部类中创建可变的局部变量。
4.可以访问外围类的成员变量。如果是static方法,则只能访问static修饰的成员变量。
匿名内部类
匿名内部类是一种特殊的内部类,这种类没有名字,通过new关键字直接创建某一个类的匿名子类的对象来使用。
1.使用匿名内部类时,我们必须是继承一个类或者实现一个接口,但是两者不可兼得,同时也只能继承一个类或者实现一个接口。
2.匿名内部类中是不能定义构造函数的。
3.匿名内部类中不能存在任何的静态成员变量和静态方法。
4.匿名内部类为局部内部类(即方法内部类),所以局部内部类的所有限制同样对匿名内部类生效。
5.匿名内部类不能是抽象的,它必须要实现继承的类或者实现的接口的所有抽象方法。
6.当所在的方法的形参需要被内部类里面使用时,该形参必须为final。
7.可以写代码块,初始化匿名内部类
8.匿名内部类可以很方便的定义回调。
9.使用内部类可以非常方便的编写事件驱动程序。
内部接口
类可以使用嵌套结构,接口同样也可以使用嵌套结构,接口种的方法我们要求出了声明的普通方法以外,子类实现接口的时候一定要覆写接口中的所有方法,但在嵌套结构下子类不强制要求实现内部接口中的方法,示例如下:
//内部接口
interface IMessage{
public void send01(String str);
interface InnerImessage{
public void send02(String str);
}
}
class MessageImp implements IMessage{
@Override
public void send01(String str) {
System.out.println(str);
}
}
public class Test01{
public static void main(String[] args) {
IMessage messageimp = new MessageImp();
messageimp.send01("zhangdapao");
}
}
另外,在JDK1.8之后提供在接口中使用static关键字来进行方法的定义,并且方法不受实例化对象的影响,使用内部类的概念进行接口的实现。
//内部接口
interface IMessage{
public void send01(String str);
//内部接口可以选择性的实现
interface InnerImessage{
public void send02(String str);
}
}
class MessageImp implements IMessage{
@Override
public void send01(String str) {
System.out.println(str);
}
//使用static定义方法,直接返回实例化对象;
public static IMessage getInstance(){
return new MessageImp();
}
}
public class Test01{
public static void main(String[] args) {
IMessage messageimp = MessageImp.getInstance();
messageimp.send01("zhangdapao");
}
}