“内部类"简单说就是在一个类的内部又定义了一个类,这个定义在已知类内部的类就称为"内部类”。由于是定义在一个已知类的内部,所以它既具备一个累的特征,又在很多方面的表现和普通类有不同。
下面,我打算从三个方面来讲解内部类的使用,并验证内部类的概念:
"内部类"虽然有不同于普通类的特性,但是它终归是类,是类就必须能创建对象并调用其中的方法来执行功能,这是定义类的意义。
我们来写一个例子,看看内部类的属性是怎么调用的:
public class innerTest { int num = 100; private class inner{ int num = 200; public void print(){ int num = 500; System.out.println(num); //方法内属性 System.out.println(this.num); //内部类属性 System.out.println(innerTest.this.num); //外部类属性 } } public static void main(String[] args) { innerTest innerT = new innerTest(); innerTest.inner inner = inner.new inner(); inner .print(); System.out.println(innerT.num + inner .num); //调用内部类的num属性 } } // 输出结果分别为:500,200,100,300内部类的特性:
"内部类"中可以定义属性,这些属性可以被其所在的普通类访问,甚至是可以访问"内部类"的私有属性(private)。当这些属性出现重名情况时,需要进行访问限定修饰;普通类的内部可以定义多个内部类和接口,并且具备继承、实现的关系;用static关键字,升级为顶级内部类,具备和普通类相同的特征,一模一样;"内部类"可以再进一步进行嵌套,构建对象时则需要按层进行构建。方法中也可以定义"内部类",方法中的"内部类"在事件处理中比较常见,在jdk1.8版本之前如果"内部类"需要访问其所在方法中的局部属性,则这个局部属性需要用final修饰。jdk1.8版本就不需要进行这个操作了,但是其本质还是final的,是不能对其进行修改的,看一个例子:
public class innerTest { public void innerMethod(){ int num = 100; class innerClass{ public void print(){ System.out.println("可以访问方法的属性,但不可以修改:"+num); } } innerClass inner = new innerClass(); inner.print(); } public static void main(String[] args) { innerTest inner = new innerTest(); inner.innerMethod(); } } //输出结果为:可以访问方法的属性,但不可以修改:100在实际开发中,我们通常用“匿名内部类”的方式来代替上面在方法中定义内部类的情况,它的写法简化很多,但意义是一样的,下面我们介绍一下:
顾名思义,匿名内部类也就是没有名字的内部类。正因为没有名字,所以匿名内部类只能使用一次,它通常用来简化代码的编写。
在使用匿名内部类时,要记住以下几个原则:
匿名内部类不能有构造方法;匿名内部类不能定义任何静态成员、方法和类;匿名内部类不能是public,protected,private,static;只能创建匿名内部类的一个实例;一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类;因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。下面我讲述一下“匿名内部类”存在的意义:
abstract class Person { public abstract void speak(); }class Child extends Person { public void speak() { System.out.println(“代码很冗余的说!!”); } }
public class Demo { public static void main(String[] args) { Person p =new Child(); p.speak(); } }
可以看到,我们用Child继承了Person类,然后实现了Child的一个实例,将其向上转型为Person类的引用。但是,如果此处的Child类只使用一次,那么将其编写为独立的一个类岂不是很麻烦?
这个时候就引入了匿名内部类,它存在的意义就是为了简化冗余的代码,如下:
abstract class Person { public abstract void speak(); }public class Demo { public static void main(String[] args) { Person p =new Person() { public void speak() { System.out.println(“代码是不是清爽了很多??”); } }; p.speak(); } }
噔噔噔噔~~ 是不是很清爽了,我们直接将抽象类Person中的方法在大括号中实现了!
其实,只要是抽象类或是接口,那么其子类中的方法都可以使用匿名内部类来实现,最常用的情况就是在多线程的实现上,因为要实现多线程必须继承Thread类或是继承Runnable接口。
常用的匿名内部类实现:
Thread类的匿名内部类实现 public class ThreadDemo { public static void main(String[] args) { Thread t =new Thread() { public void run() { for(int i = 1; i <= 5; i++) { System.out.print(i +","); } } }; t.start(); } } //输出结果:1,2,3,4,5, Runnable接口的匿名内部类实现 public class RunnableDemo { public static void main(String[] args) { Runnable r =new Runnable() { public void run() { for(int i = 1; i <= 5; i++) { System.out.print(i +" "); } } }; Thread t =new Thread(r); t.start(); } } //输出结果:1,2,3,4,5,特此声明:本文章为转载文章,仅作为学习参考,便于日后温习为目的,恭请少数关注的博友,直接点击转载博文的标题,链入原文,也算尊重原文作者的劳动。
本文链接:https://blog.csdn.net/weixin_44259720/article/details/87918110