- 一、内部类
- 二、非静态成员内部类
- 对内部类的理解
- 如何创建内部类对象
- 总结
- 三、静态成员内部类
- 使用方法
- 总结
- 私有内部静态类
- 三、局部内部类
- 总结
- 四、匿名内部类
- 总结
- 匿名内部类的作用和使用场合
一个类的成员:成员变量、成员方法、构造方法、代码块、内部类
内部类主要分为:成员非静态成员内部类、静态成员内部类、局部内部类、匿名内部类
匿名内部类是局部内部类的一种
一、内部类内部类是一类特殊的类,指的是写在类的内部的类
package Day6;
public class Dog {
//静态成员内部类
static class Tuji{
}
// 成员非静态成员内部类
class Wugui{
}
public void shoot(){
// 局部内部类
class DaShoot{
}
}
}
二、非静态成员内部类
对内部类的理解
Dog类
package Day6;
public class Dog {
// 成员变量
private String color="blue";
private String name;
private int num=40;
// 构造方法
public Dog(){
}
public Dog(String color, String name) {
this.color = color;
this.name = name;
}
//静态成员内部类
static class Tuji{
}
// 成员非静态成员内部类
class Inner{
// 成员变量
private int num=30;
private String name;
// 构造方法
public Inner(){
}
public Inner(int num, String name) {
this.num = num;
this.name = name;
}
// 成员方法
public void innerMethod(){
// 这个方法里可以做什么?
// 1.内部类可以直接访问外部类的成员(静态+非静态)
System.out.println(color);
// shoot();
// 3.如果内部类外部类有同名的变量,如何访问?
int num=20;
System.out.println(num);//20 优先访问局部变量
System.out.println(this.num);//30 内部类的
System.out.println(Dog.this.num);//40 外部类的
}
}
public void shoot(){
// 局部内部类
class DaShoot{
}
// 2.但是外部类不能直接访问内部类的成员
// 可以通过new一个内部类对象,通过对象.来访问
Inner inner = new Inner();
inner.innerMethod();
// System.out.println(inner.num);
}
}
Test类
package Day6;
public class Test {
public static void main(String[] args) {
Dog dog= new Dog();
dog.shoot();
}
}
如何创建内部类对象
第一种方法 没有import内部类
package Day6;
public class Test {
public static void main(String[] args) {
Dog dog= new Dog();
Dog.Inner inner = dog.new Inner();
//也可以将两句合成一句
Dog.Inner inner1 = new Dog().new Inner();
}
}
第二种方法 import内部类
package Day6;
import Day6.Dog.Inner;
public class Test {
public static void main(String[] args) {
Inner inner = new Dog().new Inner();
}
}
总结
- 内部类可以直接访问外部类的成员
- 外部类访问内部类要先创建内部类对象,再通过对象名调用
- 如果内部类和外部类有同名变量,需要使用外部类名.this.外部变量来调用外部类的成员变量,使用this.内部类成员变量名来调用内部类成员变量
- 必须先创建外部类对象,才能创建内部类对象(不在本类方法中)。非静态成员内部类是属于某个外部类对象的。
- 非静态内部类不能有静态方法、静态属性和静态代码块
- 外部类的静态方法、静态代码块不能访问非静态内部类(可能还没创建),包括不能使用非静态内部类定义变量、创建实例。
Dog类
package Day6.innerClass2;
public class Dog {
// 成员变量
private static String color="blue";
private static String name;
private static int num=40;
// 构造方法
public Dog(){
}
public Dog(String color, String name) {
this.color = color;
this.name = name;
}
//静态成员内部类
static class Inner{
// 成员变量
private static int num=30;
private String name;
// 构造方法
public Inner(){
}
public Inner(int num, String name) {
this.num = num;
this.name = name;
}
// 成员方法
public void innerMethod(){
int num=20;
// 静态成员内部类只能访问外部类静态成员 不能访问非静态成员
System.out.println(num);//20 优先访问局部变量
System.out.println(num);//30 内部类的 静态类可以直接访问本类中的静态成员
System.out.println(Dog.num);//40 访问静态成员直接通过类名.
}
}
}
Test类 以及静态内部类创建对象的方法
package Day6.innerClass2;
import Day6.innerClass2.Dog.Inner;
public class Test {
public static void main(String[] args) {
// Inner inner = new Dog().new Inner();
// 静态成员内部类也是属于类的,所以创建内部类对象 可以直接通过外部类.来创建
Dog.Inner inner= new Dog.Inner();
}
}
Dog.Inner inner= new Dog.Inner();
总结-
静态内部类访问静态方法可以直接用类名.,或者直接写静态方法名。不用和非静态方法一样new对象。
-
在其他的类中调用静态内部类的静态方法可以直接用类名.
Dog.Inner.innerMethod2();//可以通过类名直接.静态方法来调用静态方法
-
创建静态内部类对象
Dog.Inner inner= new Dog.Inner();
-
静态成员内部类只能访问外部类静态成员 不能访问非静态成员
-
静态类可以直接访问本类中的静态成员
-
静态类访问外部类的静态成员变量方法
System.out.println(Dog.num)
-
静态内部类不管他的静态方法还是非静态方法都是不可以调用外部类的非静态方法(因为)
私有内部静态类只限于外部类使用,不能被其他类使用,所以在其他类中没办法创建静态类对象
package Day6.innerClasss3;
public class outerClass {
private int num=10;
public void method1(){
// 此时这个局部变量num2在反编译后加上了final 所以num2的值是不能再更改的(JDK1.8)
int num2=20;
// 局部内部类
// 就像成员内部类一样,局部内部类也不使用权限修饰符
class LocalInnerClass{
private int num=30;
public void innerMethod(){
System.out.println("我是局部内部类");
System.out.println(num); //30 是当前类的
System.out.println(this.num);//30 也是当前类的
// 那么如何访问外部类的num呢?
System.out.println(outerClass.this.num);//10 外部类的num
// 如何访问局部内部类所在方法的局部变量?
System.out.println(num2);//可以直接访问
}
}
// 局部内部类的作用范围是当前方法
LocalInnerClass localInnerClass= new LocalInnerClass();
localInnerClass.innerMethod();
}
public static void main(String[] args) {
}
}
总结
- 局部内部类访外部类的成员变量
System.out.println(outerClass.this.num);//10 外部类的num
- 局部内部类访问所在方法的局部变量(此时局部变量变成了final修饰的常量,不能再更改)直接访问
System.out.println(num2);//可以直接访问
- 局部内部类访问局部内部类的成员变量
1.第一种 System.out.println(num); //30 是当前类的 2.第二种 System.out.println(this.num);//30 也是当前类的
- 局部内部类作用范围是当前方法
一个问题:为什么局部内部类访问的所在方法的局部变量要求是final的?
原因就是:局部变量在方法结束后生命周期就结束了,
但是内部类的对象却不是,所以内部类中使用局部变量的话,就需要改变量的一份拷贝。
但是既然是拷贝,就会出现两边值(局部变量和局部变量的拷贝)不一致的情况
,所以要确保同步最直接的方法就是不对该变量做修改
匿名内部类是一种特殊的局部内部类,他也是在方法中定义的
使用条件
当你对一个接口写了多个接口的实现类的时候,就需要命名多个实现类的名字,如果这个实现类只使用一次,或多或少觉得这个名气起的没必要,这时我们就可以使用匿名内部类
package Day7;
public class Test {
public static void main(String[] args) {
// new一个实现类给接口
// Compare compare=new NewCompare();
// compare.compare();
// 匿名内部类 直接使用接口名new
Compare compare=new Compare() {
@Override
public void compare() {
}
};
}
}
总结
- 匿名内部类可以实现一个接口,也可以继承一个类(可以是抽象类)
- 匿名内部类只能实现一个接口,而不是多个
- 必须实现所有的方法,匿名内部类不能是抽象类
- 匿名内部类不可能有构造方法,因为类是匿名的
- 匿名内部类没有访问修饰符
- 如果想实现构造方法的一些初始化功能,可以使用代码块实现
- 如果要访问所在方法的局部变量,该变量需要使用final修饰(JDK1.8可以省略final)



