本文已参与「新人创作礼」活动, 一起开启掘金创作之路。
👉引言💎
铭记于心 | ||
---|---|---|
🎉✨🎉我唯一知道的,便是我一无所知🎉✨🎉 |
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(); } }
🌹写在最后💖: 路漫漫其修远兮,吾将上下而求索!伙伴们,再见!🌹🌹🌹
今天的文章Java 匿名内部类与嵌套类分享到此就结束了,感谢您的阅读。
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
如需转载请保留出处:https://bianchenghao.cn/18224.html