👉引言💎
铭记于心 | ||
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉 |
Java 匿名内部类与嵌套类
1 静态嵌套类
一个类的静态成员独立于这个类的任何一个对象存在,只要在具有访问权限的地方,我们就可以通过 类名.静态成员名
的形式来访问这个静态成员,同样的,静态内部类也是作为一个外部类的静态成员而存在,创建一个类的静态内部类对象不需要依赖其外部类对象;在外部类中引用内部类非static成员变量时,首先需要先将静态内部类 new出来,并且在 内部类中无法访问外部成员
- 内部类变量既可以是 static也可以是非static的,static可被外部直接调用,而非static则用于类内部的临时使用
class t2 { public t2() { System.out.println("t2"); } static class t1 { int s=3; static int pra=5; public t1() { System.out.println(s); } } t1 t=new t1(); } public class App { public static void main(String[] args) throws Exception { new t2.t1(); System.out.println(t2.t1.pra); } }
2 内部类
2.1 内部类概述
- 特点
内部类可以直接访问外部类的成员,包括私有
外部类要访问内部类的成员,必须创建对象 - 成员内部类的定义位置
在类中方法,跟成员变量是一个位置 - 外界创建成员内部类格式
格式:外部类名.内部类名 对象名 = 外部类对象.内部类对象;
eg:t2.t1 t1 = new t2().new t1()
2.2 成员内部类的推荐使用方案
将一个类,设计为内部类的目的,大多数都是不想让外界去访问,所以内部类的定义应该私有化,私有
化之后,再提供一个可以让外界调用的方法,方法内部创建内部类对象并调用。
c++内部类与java内部类最大的区别就是:c++的内部类对象没有外部类对象的指针,不能访问外部类对象的非静态成员;java的非静态内部类对象有外部类对象的指针,能访问外部类对象的非静态成员。 java 中有多个内部类,还有匿名内部类。
2.3为什么使用内部类?
- 实现多重继承
Java中并没有提供多重继承,内部类可以实现多重继承。每个内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实现,对于内部类都没有影响。在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。 - 内部类可以有多个实例,每一个实例有独立的状态信息。
- 在一个外部类中可以有多个内部类,并且每个内部都可以实现同一个接口或者继承同一个类,但是它们的内部实现不同
- 如果外部类里没有实例化内部类,创建外部类时是不会给内部类分配内存的
2.4 内部类的创建时机:
如果内部类被实例化,那么会首先调用 内部类的构造函数,再调用外部类的,析构时恰恰反过来:
class t2 { public t2() { System.out.println("t2"); } class t1 { public t1() { System.out.println("I am static"); } } t1 t=new t1(); } public class App { public static void main(String[] args) throws Exception { t2.t1 t1 = new t2().new t1();//外部类对象.new 内部类() 的形式 } }
3 匿名内部类
3.1 匿名内部类的前提
存在一个类或者接口,这里的类可以是具体类也可以是抽象类
3.2 匿名内部类的格式
格式:new 类名 ( ) { 重写方法 } new 接口名 ( ) { 重写方法 }
new Inter() { @Override public void method(){} }
3.3 匿名内部类的本质
本质:是一个继承了该类或者实现了该接口的子类匿名对象
即可通过该匿名对象调用父类成员方法,还可以通过多态的方式接收该对象
匿名内部类可以通过多态的形式接受
Inter i = new Inter(){ @Override public void method(){ } }
3.4匿名内部类直接调用方法
interface Inter { void method(); } class Test { public static void main(String[] args){ new Inter(){ @Override public void method() { System.out.println("我是匿名内部类"); } }.method(); // 直接调用方法 } }
3.5匿名内部类在开发中的使用
当发现某个方法需要,接口或抽象类的子类对象,我们就可以传递一个匿名内部类过去,来简化传统的代码
通过匿名内部类 进行 对接口或者抽象类的 便捷实现 通常有两种情况:
- 直接 new 一个接口,并实现这个接口声明的方法,在这个过程其实会创建一个匿名内部类实现这个接口,并重写接口声明的方法,然后再创建一个这个匿名内部类的对象并赋值给前面的 类型的引用
- new 一个已经存在的类 / 抽象类,并且选择性的实现这个类中的一个或者多个非 final 的方法,这个过程会创建一个匿名内部类对象继承对应的类 / 抽象类,并且重写对应的方法
interface Go { void CreateO(); } class Person1 implements Go { @Override public void CreateO() { System.out.println("七夕已到,我Person1想找对象"); } } class Person2 implements Go { @Override public void CreateO() { System.out.println("七夕已到,我Person2想找对象"); } } class Test { public static void main(String[] args) { //如果没有匿名内部类,就要通过实现接口的实现类进行函数调用 Person1 person1 = new Person1(); Person2 person2 = new Person2(); test(person1); test(person2); } static void test(Go g) { g.CreateO(); } }
- 反之,如果有匿名内部类,则会简化很多
interface Go { void CreateO(); } class Test { public static void main(String[] args) { test(new Go(){ public void CreateO() { System.out.println("七夕已到,我Person1想找对象"); } }); test(new Go(){ public void CreateO() { System.out.println("七夕已到,我Person2想找对象"); } }); } static void test(Go g) { g.CreateO(); } }
- 在匿名内部类的基础上进行更简化的就是lambda表达式的使用(注意,Java8是不支持lambda表达式语法的,只有11及以上的jdk支持)
interface Go { void CreateO(); } class Test { public static void main(String[] args) { test(()-> System.out.println("我想找对象")); } static void test(Go g) { g.CreateO(); } }
4 局部类(较少使用)
- 局部内部类定义位置
局部内部类是在方法中定义的类 - 局部内部类方式方式
局部内部类,外界是无法直接使用,需要在方法内部创建对象并使用
该类可以直接访问外部类的成员,也可以访问方法内的局部变量
public class App { public int f1 = 1; public App() { System.out.println("创建 " + this.getClass().getSimpleName() + " 对象"); } private void localInnerClassTest() { // 局部内部类 A,只能在当前方法中使用 class A { // static int field = 1; // 编译错误!局部内部类中不能定义 static 字段 public A() { System.out.println("创建 " + A.class.getSimpleName() + " 对象"); System.out.println("其外部类的 f1 字段的值为: " + f1); } } A a = new A(); } public static void main(String[] args) { App test = new App(); test.localInnerClassTest(); } }
🌹写在最后💖: 路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹