内部类
定义在类里面的类,这个作为其他外部类存在,并且可以实现多个类嵌套
一、成员内部类:在类中定义(在方法外),与当前类的成员属性、方法同级(把成员内部类当成是类中的方法理解)
代码实现
package day22;
/**
* 外部类
* @author jun
*/
public class Outer {
private String name = "外部";
private int i = 6;
/**
* 外部方法
*/
public void outer_f1() {
System.out.println("外部类方法");
}
public void outer_f2() {
//访问内部类。要先创建对象
inner inner = new inner();
//在外部类访问内部类的方法与属性
System.out.println(name);
System.out.println(i);
System.out.println(inner.name);
System.out.println(inner.i);
inner.outer_f1();
inner.inner_f1();
}
/**
* 内部类,与外部类中的属性和方法同级
* 可以使用任意的访问修饰符
* @author jun
*
*/
public class inner{
//内部类中不能定义静态的
//可与外部类拥有相同的属性和方法
private String name = "内部";
private int i = 3;
public void outer_f1() {
System.out.println("与外部类相同的方法");
}
/**
* 内部类的方法
*/
public void inner_f1() {
//可以直接使用外部类的属性和方法
System.out.println(name);
System.out.println(i);
//如果有同名的默认使用当前类的,如果要指定使用外部类的
//用外部类.this.属性/方法
System.out.println(Outer.this.name);
System.out.println(Outer.this.i);
outer_f1();
Outer.this.outer_f1();
}
}
}
--------------------------------------------------------------------------------------------------------
package day22;
public class Demo {
public static void main(String[] args) {
//其他类访问某个类的内部类,需要先创建外部类对象
Outer outer = new Outer();
outer.outer_f2();
//通过外部类对象.new 内部类()的方式创建对象
Outer.inner inner = outer.new inner();
inner.outer_f1();
inner.inner_f1();
}
}
二、 局部内部类:在类中定义(在方法内),与局部变量同级(把局部类当成是方法中的局部变量理解)
代码实现
public class Outer {
private String name;
private int i = 3;
/**
* 外部方法
*/
public void outer_f1() {
int i = 1;
/**
* 局部内部类,在方法内创建,与局部变量类似
* 不可有访问修饰符
* 内部类的使用范围只有当前方法内
* @author jun
*/
class inner{
//可以有相同 的属性和方法
private String name;
public void outer_f1() {
}
public void inner_f1() {
//就近原则,可以访问方法内的局部变量与类中的属性
System.out.println(i);
//调用外部类的属性与方法和成员内部类一致
System.out.println(Outer.this.i);
}
}
//在使用时,需要写在内部类的后面,先声明内部类,再使用
inner in = new inner();
in.inner_f1();
}
}
三、静态内部类:用static修饰的成员内部类,与静态属性、静态方法同级(把静态内部类当成类中的静态方法理解)
代码实现
public class Outer {
private String name;
private int i;
/**
* 外部方法
*/
public void outer_f1() {
}
/**
* 静态内部类,拥有静态的特性
* @author jun
*/
static class Inner{
static int i =1;
static void inner_f1() {
System.out.println("inner_f1");
}
int j = 1;
public void inner_f2() {
}
}
}
--------------------------------------------------------------------------------------------------------
package day22.innerclass.staticclass;
import day22.innerclass.staticclass.Outer.Inner;
public class Demo {
public static void main(String[] args) {
//静态的内部类,可以直接使用,不依赖外部类
Inner inner = new Inner();
inner.inner_f2();
System.out.println(Inner.i);
Inner.inner_f1();
}
}
四、匿名内部类:也是一种特殊的局部内部类(在方法内定义)
- 实现匿名内部类两种方法:
继承一个类,重写其方法;
实现一个接口(可以是多个),实现其方法。
匿名内部类不能有构造方法。
匿名内部类不能定义任何静态成员、方法和类。
匿名内部类不能是public,protected,private,static。
只能创建匿名内部类的一个实例。
一个匿名内部类一定是在new的后面,用其隐含实现一个接口或实现一个类。
因匿名内部类为局部内部类,所以局部内部类的所有限制都对其生效。
代码实现
package day22.innerclass.anonymity;
/**
* 测试接口
* @author jun
*/
public interface TestInterface {
/**
* 返回一个字符串
* @return
*/
public String getStr();
}
--------------------------------------------------------------------------------------------------------
package day22.innerclass.anonymity;
/**
* 测试继承类
* @author jun
*/
public abstract class TestExtends {
public String name;
public abstract void show();
}
--------------------------------------------------------------------------------------------------------
package day22.innerclass.anonymity;
public class Demo {
public static void main(String[] args) {
TestInterface test = new TestClass();
System.out.println(test.getStr());
//可以使用匿名内部类简化接口的使用
TestInterface test1 = new TestInterface(){ //匿名内部类,是一个实现了当前接口的类
@Override
public String getStr() {
return "Hello 匿名内部类!!";
}
};
System.out.println(test1.getStr());
//使用匿名内部类简化继承的使用
TestExtends test2 = new TestExtends() { //匿名内部类,是一个继承了当前类的内部类
@Override
public void show() {
System.out.println(name);
}
};
test2.name = "张三";
test2.show();
}
}
总结:
内部类的访问规则:
1、内部类可以直接访问外部类中的成员,包括私有。
之所以可以直接访问外部类中的成员,是因为内部类中持有了一个外部类的引用,格式 外部类名.this
2、外部类要访问内部类,必须建立内部类对象。
访问格式:
1,当内部类定义在外部类的成员位置上,而且非私有时,可以直接建立内部类对象,在外部其他类中进行访问,
格式
外部类名.内部类名 变量名 = 外部类对象.内部类对象;
Outer.Inner in = new Outer().new Inner();
2,当内部类在成员位置上,就可以被成员修饰符所修饰。
- 比如,private:将内部类在外部类中进行封装。
static:内部类就具备static的特性。
当内部类被static修饰后,只能直接访问外部类中的static成员。出现了访问局限。
在外部其他类中,如何直接访问static内部类的非静态成员呢?
new Outer.Inner().function();
在外部其他类中,如何直接访问static内部类的静态成员呢?
Outer.Inner.function();
* 注意:当内部类中定义了静态成员,该内部类必须是static的。
当外部类中的静态方法访问内部类时,内部类也必须是static的
使用场景:
当描述事物时,事物的内部还有事物,该事物用内部类来描述。因为内部事务在使用外部事物的内容。
内部类定义在局部时,
1、不可以被成员修饰符修饰
2、可以直接访问外部类中的成员,因为还持有外部类中的引用。
但是不可以访问它所在的局部中的变量。只能访问被final修饰的局部变量。