Java内部类
程序媛 泡泡 人气:01 内部类概述
如果一个类存在的意义就是为指定的另一个类,可以把这个类放入另一个类的内部。
就是把类定义在类的内部的情况就可以形成内部类的形式。
A类中又定义了B类,B类就是内部类,B类可以当做A类的一个成员看待:
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(){ @Override public void save() { System.out.println("save()..."); } @Override public void get() { } }.save(); //5.创建抽象类对应的匿名对象与匿名内部类 new Inter2(){ @Override public 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("我们会越来越强的!"); } }
总结: 匿名内部类属于局部内部类,而且是没有名字的局部内部类,通常和匿名对象一起使用
加载全部内容