欢迎您访问365答案网,请分享给你的朋友!
生活常识 学习资料

七、内部类

时间:2023-06-13
目录

成员内部类

简单概述代码举例讲解浅谈内部类 局部内部类

初步理解代码理解总结 匿名内部类

代码讲解 成员内部类 简单概述

简而言之就是定义在一个类内部的类

接下来讲点注意点,就举例子理解

1、方法内部不能定义方法,但类的内部可以再次定义类

2、包含类的特点,但也有成员属性的限制

3、外部类的修饰符只有 [public、默认的],但内部类的修饰限定符和成员属性一样,比如static、final

接下来详细的使用方法都会在代码中举例、注释

代码举例讲解

package 内部类;public class Outer { private int num = 10; static int age = 20; public class Inner{ private int age; private int num; public void methodInner(){ System.out.println("这是内部类方法"); System.out.println(num);//优先访问靠近的,都是一样的 System.out.println(age); //成员与方法的调用一样 System.out.println(this.age);//指的是内部类的变量 System.out.println(Outer.this.num);//是外部类的变量 System.out.println(Outer.age);//非静态成员可以访问静态成员 } } //内部类之间的继承, // 当然接口的继承都是可以的,对于其他类、外部类(没必要,本来就可以访问外部类元素)都是可以继承的 //抽象类、接口哪些就不一一举例了,基本都是一样的 public class SubInner extends Inner{ @Override//重写,都是满足类的功能的 public void methodInner() { super.methodInner(); } } public void method1(){ //这里可以创建内部类,但是静态方法,就不能创建非静态内部类,可以考虑内存的加载 //但静态方法可以通过创建外部类来创建内部类,即主方法的演示 System.out.println("这是外部类方法"); Inner inner = new Inner();//可以创建内部类成员、用内部类成员调用相应数据 inner.methodInner(); } public static void main(String[] args) { Outer test1 = new Outer(); test1.method1(); //如果想要创建内部类对象 //静态访问非静态,需要借用外部类 Outer.Inner inner = test1.new Inner(); //如果访问别的类中的静态内部类Outer.Inner inner = new Outer.Inner(); //访问别的类中的非静态内部类Outer.Inner inner = outer.new Inner(); //如果内部类是静态的可以这样创建内部类:Inner inner = new Inner();静态之间是可以直接访问的 inner.methodInner(); }}

浅谈内部类

根据上面知识点总结一下

非静态内部类的特点
  在非静态内部类中不能定义static修饰的属性,方法,代码块。
  在非静态内部类中可以调用外部类的属性,方法。
  在非静态内部类的方法中可以调用外部类的属性,方法,满足就近原则。
  如果出现同名?怎么区分?外部类的属性或方法外部类的名 、this.属性|方法();
  可以访间外部类static修饰的属性或方法吗?可以的
 如何调用非静态内部的属性或方法呢?
  1)在外部类的中进行?
    外部类非静态方法:直接创建内部类的对象,然后通过对象进行调用属性或方法
    外部类静态方法:创建外部类的对象,再根据外部类对象.new 内部类()语法创建内部类对象通过内部类对象调用属性和方法
  2)在其他的类中如何调用?
创建外部类的对象,再根据外部类对象、new内部类()语法创建内部类对象通过内部类对象调用属性和方法


静态内部类的特点
  static修饰的,可以再静态内部类中使用static关键字来修饰属性和方法,以及代码块。
  再静态内部类中,只能调用外部类中静态的属性和方法。在静态内部类中不能使用外部类名 、this
  再静态内部类中不能使用this关键字?
    错误的,再静态内部类中可以定义非静态的方法。可以再非静态方法中使用this关键字,调用该静态内部类中定义的非静态属性和方法。但是不能使用外部类 、this
  如果想调用静态内部类中的属性和方法:
    如果是静态成员,可以直接通过静态内部类名,进行调用, 如果再其 他类中可以通过外部类.内部类.静态成员
    如果是非静态成员,必须得创建静态内部类的对象通过对象名。进行调用:外部类.内部类对象名= new 外部类 .内部类();
注意:内部类可以创建对象也是因为在内部类中有构造方法。如果显示添加带参构造方法,new对象的时候,必须传递参数。

基本了解了之后,我们研究一下内部类的好处。要我说也就是解决的java中单继承的弊端,每一个内部类都可以独自继承一个类、接口、抽象类,这样就可以丰富类的功能,但说的很不专业,还是在上一下专业术语。

为什么要使用内部类?在《Think in java》中有这样一句话:使用内部类最吸引人的原因是:每个 内部类都能独立地继承一个(接口的)实现,所以无论外围类是否已经继承了某个(接口的)实 现,对于内部类都没有影响。 在我们程序设计中有时候会存在一些使用接口很难解决的问题,这个 时候我们可以利用内部类提供的、可以继承多个具体的或者抽象的类的能力来解决这些程序设计问 题。可以这样说,接口只是解决了部分问题,而内部类使得多重继承的解决方案变得更加完整。使 用内部类最大的优点就在于它能够非常好的解决多重继承的问题,但是如果我们不需要解决多重继 承问题,那么我们自然可以使用其他的编码方式,但是使用内部类还能够为我们带来如下特性(摘 自《Think in java》):

  1、内部类可以用多个实例,每个实例都有自己的状态信息,并且与其他外围对象的信息相互独 立。

  2、在单个外围类中,可以让多个内部类以不同的方式实现同一个接口,或者继承同一个类。

  3、创建内部类对象的时刻并不依赖于外围类对象的创建。

  4、内部类并没有令人迷惑的“is-a”关系,他就是一个独立的实体。

  5、内部类提供了更好的封装,除了该外围类,其他类都不能访问。

成员内部类也是最普通的内部类,它是外围类的一个成员,所以他是可以无限制的访问外围类的所 有 成员属性和方法,尽管是private的,但是外围类要访问内部类的成员属性和方法则需要通过内 部类实例来访问.

局部内部类 初步理解

基本一样,这里只提一下不同点

1、定义在代码块中,只有在代码块中有效,和局部变量一样

2、没有访问修饰符,没有static,和局部变量是一样的

3、相关特性和局部变量一致,也包含类的属性
4、局部内部类无法访问同名局部变量

代码理解

package 内部类;public class Part { { class inner1{ } } int age = 44; static int name = 33; static { int name = 22; class inner2{ public int name = 12; int age = 13; public void test(){ System.out.println(name); System.out.println();//局部内部类无法访问同名局部变量 System.out.println(Part.name);// System.out.println(Part.this.age); //System.out.println(Part.age);静态不能访问非静态 } } inner2 i = new inner2(); i.test(); } public void f(){ class inner3{ } } public static void main(String[] args) { class inner4{ } }}

总结

局部内部类:
 位置在方法中,代码块中,构造方法中。作用范围也只能在声明他的语句块中。
 局部内部类不能用访问修饰符修饰,也不能用static修饰。所以局部 内部类中定义的属性和方法以及代码块是非静态的。
 局部内部类可以访问外部类中声明的属性和方法。[看局部内部类所在的块是否是静态决定能够访问哪些成员]
 如果使用?创建局部内部类的对象,通过局部内部类对象名。进行访问.
 局部内部类的方法可以访问所在的块声明的局部变量,在jdk1 .7前该变量必须是final修饰的,但是jdk8后不要求了。

匿名内部类

匿名类,就是没有名称的类,其名称由Java编译器给出,一般是形如:外部类名称+$+匿名类顺 序,没有名称也就是其他地方就不能引用,不能实例化,只用一次,当然也就不能有构造器。 匿名类根据位于地方不同分为:成员匿名类和局部匿名类。

匿名类不能使用任何关键字和访问控制符,匿名类和局部类访问规则一样,只不过内部类显式的定 义了一个类,然后通过new的方式创建这个局部类实例,而匿名类直接new一个类实例,没有定义 这个类。匿名类最常见的方式就是回调模式的使用,通过默认实现一个接口创建一个匿名类然后, 然后new这个匿名类的实例。

代码讲解

先写一个接口

package 内部类;public interface Inter { public void f();}

匿名内部类的实现

package 内部类;public class Test { public void test(Inter inter){//传进来的接口并没有实现 inter.f(); } public static void main(String[] args) { Test t = new Test(); //方法一:只是用一次 t.test(new Inter() { @Override public void f() { System.out.println("测试"); } }); //方法二:可以多次使用,所以接口没有实现的话,这种方法也是可以使用的 Inter inter = new Inter() { @Override public void f() { System.out.println("测试"); } }; t.test(inter); }}

Copyright © 2016-2020 www.365daan.com All Rights Reserved. 365答案网 版权所有 备案号:

部分内容来自互联网,版权归原作者所有,如有冒犯请联系我们,我们将在三个工作时内妥善处理。