1、基本介绍:一个类的内部又完整的嵌套了一个类。被嵌套的内称为内部类。
2、最大的特点:就是可以直接访问私有属性,并且可以贴现类与类之间的包含关系。
3、基本语法:
class Outer{//外部类
class Inner{内部类
}
}
class Other{
//外部其他类
}
回想类的5大成员:成员方法、构造器、代码块、内部类、成员属性
4、内部类的分类
- 定义在外部类局部位置上(比如方法内)
- 局部内部类(有类名)
- 匿名内部类(没有类名,重点)
- 定义在外部类的成员位置上:
- 成员内部类(没有static修饰)
- 静态内部类(使用static修饰)
5、局部内部类
/**
* 演示局部内部类
* (1)不能添加访问修饰符,因为他的地位就是一个局部变量。局部变量是不能使用访问修饰符的,但是可以shiyong
* final修饰。
*
*/
public class LocalInnerClass {
public static void main(String[] args) {
Outer02 outer02 = new Outer02();
}
}
class Outer02{
private int n1 = 100;
private void m2(){//私有方法
System.out.println("javk");
}
public void m1(){
class Inner02{//局部内部类
//可以直接访问外部类的所有成员,包含私有的chengyuan.
public void f1(){
System.out.println("n1 = " + n1);
m2();
}
}
class Inner03 extends Inner02{
}
//外部类在方法中,可以创建Inner02对象,然后调用方法即可。
Inner02 inner02 = new Inner02();
inner02.f1();
}
}
小结:(1)局部内部类定义在方法中/代码块中(2)作用域在方法体或者是代码块中(3)本质荣然是一个类。(4)其他的外部类是不能访问局部内部类的,我脸创建对象都只能在本方法中。(5)
// 如果外部类和局部内部类的成员重名是=时,默认遵循就近原则,如果想访问外部类的成员
// 规则如下:外部类名.this.成员 Outer02.this.n1
6、匿名内部类-------->为了解决简化开发,比如说我的某个类只使用一次。
说明:匿名内部类定义在外部类的局部位置,比如方法中,并且没有类名(名字是系统分配的)。其实就是在jdk 的内部给你创建了一个新的类或者是显示了一个接口,只不过这个类是系统给的,我们看不见。他继承了你new 的那个类。
(1)本质上是一个类(2)内部类(3)这个类,没有名字(4)同时还是一个对象
怎么样获取一个类的 运行类型:对象.getClass()
- new 类/接口(参数列表){
- 类体
- };//这里还有个逗号。
package innerclass;
public class AnonymousnnerClass {
public static void main(String[] args) {
Outer04 outer04 = new Outer04();
outer04.method();
}
}
class Outer04 {
private int n1 = 10;
public void method() {
//1.看一个需求:想使用A接口,实现该接口并创建对象
//若Tiger类只使用一次,后面不在使用就可以是用匿名内部类,来简化开发
// A tiger = new Tiger();
// tiger.cry();
//在这里编译类型是:A。
//运行类型是 匿名内部类 ----> XXXX = > Outer04$1
//怎么样获取一个类的 运行类型:对象.getClass()
/*底层的代码是这样的
我们只使用一次Tiger类
class XXX implements A {
@Override
public void cry() {
System.out.println("我们一起学猫叫 ");
}
}
*/
//在jdk底层创建匿名内部类 Outer04$1,立刻就创建了 Outer04$1,并且把地址放回给tiger
A tiger = new A(){
@Override
public void cry() {
System.out.println("我们一起学猫叫 ");
}
};
//这里还有一个分号。
tiger.cry();
}
}
interface A {
public void cry();
//接口中的方法是没有方法体的
}
//class Tiger implements A {
//
//
// @Override
// public void cry() {
// System.out.println("我们一起学猫叫 ");
// }
//}
class Father {
public Father(String name) {
}
public void test() {
}
}
package enumeration;
import java.lang.reflect.Array;
import java.util.Arrays;
import java.util.Comparator;
public class sort {
public static void main(String[] args) {
int[] arr = {1 , 2 , -1 , 75};
sortBubble(arr);
System.out.println(Arrays.toString(arr));
System.out.println("=======");
bubble01(arr, new Comparator() {
@Override
public int compare(Object o1, Object o2) {
Integer m = (Integer)o1;
Integer n = (Integer)o2;
return m - n;
}
});
}
public static void sortBubble(int[] arr){
int temp = 0;
for(int i = 0;i < arr.length - 1;i++){
for(int j = 0;j < arr.length - 1 - i;j++){
//升序的话
if (arr[j] > arr[j+1]){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
public static void bubble01(int[] arr,Comparator c){
int temp = 0;
for(int i = 0;i < arr.length - 1;i++){
for(int j = 0;j < arr.length - 1 - i;j++){
//升序的话
if (c.compare(arr[j],arr[j+1]) > 0){
temp = arr[j];
arr[j] = arr[j+1];
arr[j+1] = temp;
}
}
}
}
}
实例:
package innerclass;
public class Anomymous {
public static void main(String[] args) {
picture picture = new picture();
f1(picture);
//简化写法
f1(new IL() {
@Override
public void show() {
System.out.println("坚持下去");
}
});//这里的逗号有意思哦。
}
public static void f1(IL il){
il.show();
}
}
interface IL{
public void show();
}
class picture implements IL{
@Override
public void show() {
System.out.println("我爱你塞北的雪");
}
}
2.
package innerclass;
public class Anomymous001 {
public static void main(String[] args) {
new CellPhone().alarmClock(new Bell() {
@Override
public void ring() {
System.out.println("我一定要加油啊");
}
});
}
//实现了Bell接口的匿名内部类。
}
interface Bell{
void ring();
}
class CellPhone {
public void alarmClock(Bell bell){
bell.ring();
}
}
成员内部类:就是将类建立在一个类的内部,前面的匿名内部类大多都是建立在方法内部的。
public class Anomymous002 {
public static void main(String[] args) {
//怎么获得内部的一个类对象呢。一个方法就是调用方法getInner001
//Outer001.Inner001 inner001 = new Outer001().getInner001();
Outer001 outer001 = new Outer001();
Outer001.Inner001 inner001 = outer001.getInner001();
//还有一种方式就是将内部的类看成一个成员变量来看。
final Outer001.Inner001 inner0011 = outer001.new Inner001();
inner001.say();
//第三种
Outer001.Inner001 inner0012 = new Outer001().new Inner001();
}
}
class Outer001{
private int n1 = 10;
public String name = "张三";
private void hi(){
System.out.println("我要稳稳 的幸福");
}
public class Inner001{
public double sal = 18000;
public int n1 = 18000;
//如果成员内部类的成员
// 和外部的成员重名了,会遵循就近原则,如果想访问外部的变量
//格式:外部的类名.this.变量名(Outer001.this.n1)
public void say(){
System.out.println("sal = " + sal+ "外部你n1 = " + Outer001.this.n1);
}
}
public Inner001 getInner001(){
return new Inner001();
}
}
总结:访问的时候记住一点就是内部类就看成外部类的一个变量。怎么使用自己想想看。(想使用这个变量当然要创建对象啦或者在内部创建一个方法。)
- 局部内部类
- 匿名内部类
- 前两种放在方法或者代码块中的
- 成员内部类
- 静态内部类--------new 类/接口(参数列表){};重点
- 后两个是放在外部类的成员位置,本质就是一个成员,所以他的使用也就很明了了。
创建一个对象就会开辟一个空间,创建一个,开辟一个。