> 文章列表 > JAVA 内部类

JAVA 内部类

JAVA 内部类

JAVA 内部类

目录

  • JAVA 内部类
    • 1 内部类概述
    • 2 特点
    • 3 练习 : 内部类入门案例
    • 4 成员内部类
      • 4.1 练习 : 被private修饰
      • 4.2 练习 : 被static修饰
    • 5 局部内部类
    • 6 匿名内部类
    • 7内部类总结

1 内部类概述

如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。
就是把类定义在类的内部的情况就可以形成内部类的形式。
A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待:
JAVA 内部类

2 特点

  1. 内部类可以直接访问外部类中的成员,包括私有成员
  2. 外部类要访问内部类的成员,必须要建立内部类的对象
  3. 在成员位置的内部类是成员内部类
  4. 在局部位置的内部类是局部内部类

3 练习 : 内部类入门案例

创建包: cn.tedu.innerclass
创建类: TestInner1.java

package cn.tedu.innerclass;
/*本类用作测试内部类的入门案例*/
public class TestInner1 {public static void main(String[] args) {//3.创建内部类对象,使用内部类的资源/*外部类名.内部类名 对象名 = 外部类对象.内部类对象*/Outer.Inner oi = new Outer().new Inner();oi.delete();System.out.println(oi.sum);//4.调用外部类的方法--这样是创建了一个外部类的匿名对象,只使用一次new Outer().find();}
}//1.创建外部类 Outer
class Outer{//1.1创建外部类的成员变量String name;private int age;//1.2创建外部类的成员方法public void find(){System.out.println("Outer...find()");//6.测试外部类如何使用内部类的资源//System.out.println(sum);--不能直接使用内部类的属性//delete();--不能直接调用内部类的方法/*外部类如果想要使用内部类的资源,必须先创建内部类对象* 通过内部类对象来调用内部类的资源*/Inner in = new Inner();System.out.println(in.sum);in.delete();}//2.创建内部类Inner--类的特殊成员/*根据内部类位置的不同,分为:成员内部类(类里方法外)、局部内部类(方法里)*/class Inner{//2.1定义内部类的成员变量int sum = 10;//2.2定义内部类的成员方法public void delete(){System.out.println("Inner...delete()");//5.测试内部类是否可以使用外部类的资源/*结论:内部类可以直接使用外部类的资源,私有成员也可以!*/System.out.println(name);System.out.println(age);/*注意:此处测试完毕需要注释掉,否则来回调用* 会抛出异常StackOverFlowException栈溢出异常*///find();}}
}

4 成员内部类

4.1 练习 : 被private修饰

创建包: cn.tedu.innerclass
创建类: TestInner2.java

package cn.tedu.innerclass;
/本类用来测试成员内部类被private修饰*/
public class TestInner2 {public static void main(String[] args) {/怎么使用内部类Inner2的资源?*///4.创建内部类Inner2对象进行访问//Outer2.Inner2 oi = new Outer2().new Inner2();//oi.eat();/如果Inner2被private修饰,无法直接创建对象该怎么办?*///7.创建外部类对象,间接访问私有内部类资源new Outer2().getInner2Eat();}
}
//1.创建外部类Outer2
class Outer2{//6.提供外部类公共的方法,在方法内部创建Inner2内部类对象,调用内部类方法public void getInner2Eat() {Inner2 in = new Inner2();//外部类可以访问内部类的私有成员in.eat();}//2.1创建成员内部类Inner2/成员内部类的位置:类里方法外*///5.成员内部类,被private修饰私有化,无法被外界访问private class Inner2{//3.创建内部类的普通成员方法public void eat() {System.out.println("我是Inner2的eat()");}}
}

总结:
成员内部类被Private修饰以后,无法被外界直接创建创建对象使用
所以可以创建外部类对象,通过外部类对象间接访问内部类的资源

4.2 练习 : 被static修饰

创建包: cn.tedu.innerclass
创建类: TestInner3.java

package cn.tedu.innerclass;
/本类用来测试成员内部类被static修饰*/
public class TestInner3 {public static void main(String[] args) {/如何访问内部类的show()?*///4.创建内部类对象访问show()//方式一:按照之前的方式,创建内部类对象调用show()//Outer3.Inner3 oi = new Outer3().new Inner3();//oi.show();//方式二:创建匿名内部类对象访问show()//new Outer3().new Inner3().show();/现象:当内部类被static修饰以后,new Outer3()报错*///6.用static修饰内部类以后,上面的创建语句报错,注释掉//通过外部类的类名创建内部类对象Outer3.Inner3 oi = new Outer3.Inner3();oi.show();//7.匿名的内部类对象调用show()new Outer3.Inner3().show();//9.访问静态内部类中的静态资源--链式加载Outer3.Inner3.show2();}
}//1.创建外部类Outer3
class Outer3{//2.创建成员内部类Inner3//5.内部类被static修饰—并不常用!浪费内存!static class Inner3{//3.定义成员内部类中普通的成员方法public void show() {System.out.println("我是Inner3类的show()");}//8.定义成员内部类的静态成员方法static public void show2() {System.out.println("我是Inner3的show2()");}}
}

总结:
静态资源访问时不需要创建对象,可以通过类名直接访问
访问静态类中的静态资源可以通过”. . . ”链式加载的方式访问

5 局部内部类

创建包: cn.tedu.innerclass
创建类: TestInner4.java

package cn.tedu.innerclass;
/本类用来测试局部内部类*/
public class TestInner4 {public static void main(String[] args) {/如何使用内部类的资源呢?* 注意:直接调用外部类的show()是无法触发内部类功能的* 需要再外部类中创建内部类对象并且进行调用,才能触发内部类的功能* *///5.创建外部类对象调用show()//7.当在外部类show()中创建局部内部类对象并且进行功能调用后,内部类的功能才能被调用new Outer4().show();}
}
//1.创建外部类Outer4
class Outer4{//2.创建外部类的成员方法public void show() {//3.创建局部内部类Inner4—不太常用!!!/位置:局部内部类的位置在方法里*/class Inner4{//4.创建局部内部类的普通属性与方法String name;int age;public void eat() {System.out.println("我是Inner4的eat()");}}/如何使用局部内部类的资源?*///6.在show()里创建内部类对象Inner4 in = new Inner4();in.eat();System.out.println(in.name);System.out.println(in.age);}
}

6 匿名内部类

创建包: cn.tedu.innerclass
创建类: TestInner5.java

package cn.tedu.innerclass;
/*本类用于测试匿名内部类
* 匿名内部类没有名字,通常与匿名对象结合在一起使用*/
public class TestInner5 {public static void main(String[] args) {//传统方式:创建接口的实现类+实现类实现接口中的抽象方法+创建实现类对象+通过对象调用方法//3.创建接口一对应的匿名对象与匿名内部类,并调用实现了的方法save()new Inter1(){@Overridepublic void save() {System.out.println("save()...");}@Overridepublic void get() { }}.save();//5.创建抽象类对应的匿名对象与匿名内部类new Inter2(){@Overridepublic void drink() {System.out.println("一人饮酒醉");}}.drink();//7.调用普通类的功能怎么调用?创建匿名对象直接调用new Inter3().powerUp();new Inter3().powerUp();//new了2次,所以是两个匿名对象/*如果想要多次使用实现后的功能,还是要创建普通的对象* 匿名对象只能使用一次,一次只能调用一个功能* 匿名内部类其实就充当了实现类的角色,去实现未实现的抽象方法,只是没有名字而已*/Inter3 in = new Inter3();in.study();in.study();in.study();in.study();in.study();in.study();}
}//1.创建接口
interface Inter1{//2.定义接口中的抽象方法void save();void get();
}
//4.创建抽象类
abstract class Inter2{public void play(){System.out.println("Inter2...play()");}abstract public void drink();
}
//6.创建普通类
class Inter3{public void study(){System.out.println("什么都阻挡不了我想学习赚钱的决心");}public void powerUp(){System.out.println("我们会越来越强的!");}
}

总结:
匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用

7内部类总结

1.内部类创建对象的格式:
外部类名.内部类名 对象名 = 外部类对象.内部类对象

2.根据内部类的位置不同,分为:
成员内部类(类里方法外)
局部内部类(方法里)

3.内部类可以直接使用外部类的资源,外部类使用内部类资源时,
需要先创建内部类的对象,通过内部类对象来调用

4.成员内部类被private修饰后,需要在外部类创建公共方法,间接访问内部类的资源

5.静态内部类不需要先创建外部类对象,
而是要先通过外部类的类名找到内部类,再创建内部类的对象

5.如果静态内部类有静态资源,可以不创建一个对象,就通过
外部类名.内部类名.静态资源名 的链式加载的方式,使用资源

7.直接创建外部类对象,调用局部内部类所处的方法时,并不会触发内部类的功能
需要在内部类所处的方法中,创建内部类对象,并调用其功能,功能才会被触发

8.匿名内部类没有名字,通常与匿名对象结合在一起使用

9.如果想要多次使用实现后的功能,还是要创建之前的普通对象
匿名对象只能使用一次,一次只能调用一个功能
匿名内部类其实就是充当了实现类的功能,去实现未实现的方法,只是没有名字而已