Java基础-内部类
成员内部类
-
当一个类定义在另一个类里面,我们就称这个类为成员内部类
public class Outer { private String id; public void out (){ System.out.println("这是外部类的方法"); } class Inner{ //成员内部类 public void in(){ System.out.println("这是内部类的方法"); } } }
这样看起来 Inner就像是Outer的一个成员,Outer称为外部类,Inner称为内部类。成员内部类可以访问外部类的所有成员(包括私有成员和静态成员)
-
成员内部类的创建是是依附外部类的,也就是说想要创建内部类对象则必须创建一个外部对象
public class Outer {
//成员内部类
class Inner {
public void in() {
System.out.println("这是内部类");
}
//内部类的构造方法
Inner() {
System.out.println("Inner的构造方法");
}
}
//外部类的构造方法
public Outer() {
System.out.println("Outer的构造方法");
}
//外部类的普通方法
public void out() {
System.out.println("这是外部类");
}
}
class Application {
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();
}
}
当创建成员内部类时,程序会先执行外部类的构造方法再执行内部类的构造方法
- 内部类可以使用外部类中所有私有属性和方法
public class Outer {
private String id="123";
//成员内部类
class Inner {
public void in() {
out();
System.out.println(id);
System.out.println("这是内部类的方法");
}
}
//外部类的普通方法
public void out() {
System.out.println("这是外部类的方法");
}
}
class Application {
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();
inner.in();
}
}
- 如果内部类成员和外部类的成员有相同名字,则程序默认调用的是内部类的成员,如果想调用外部的成员则需要”外部类名.this.成员变量“;
public class Outer {
private String id="123";
//成员内部类
class Inner {
public void in() {
Outer.this.out();
}
public void out() {
System.out.println("这是内部部类的方法");
}
}
//外部类的普通方法
public void out() {
System.out.println("这是外部类的方法");
}
}
class Application {
public static void main(String[] args) {
Outer.Inner inner = new Outer().new Inner();
inner.in();
}
}
- 如果内部类的外部类要问内部类的话,并不能直接访问,外部类必须要创建内部类的对象,即可访问内部类的所有成员(包括私有成员);
public class Outer {
//成员内部类
class Inner {
//内部类的普通方法
public void in() {
System.out.println("这是内部部类的方法");
}
}
//外部类的普通方法
public void out() {
Inner inner = new Inner();
inner.in();
}
}
class Application {
public static void main(String[] args) {
Outer outer = new Outer();
outer.out();
}
}
- 记录问题:
public interface InterfaceTest {
void test01();
void test02();
class Test{//接口的成员内部类
public void printf(InterfaceTest interfaceTest){
interfaceTest.test01();
interfaceTest.test02();
}
}
public static void main(String[] args) {//接口的静态方法
demo03.Test.Test01 test01 = new demo03.Test().new Test01();//成员内部类需要先初始化外部类再实例化内部类
}
}
class Test{
public static void main(String[] args) {
InterfaceTest.Test test =new InterfaceTest.Test();//接口内部类可以直接实例化 无需使用static修饰成员内部类
}
class Test01{//普通类的成员内部类
public void printf(InterfaceTest interfaceTest){
interfaceTest.test01();
interfaceTest.test02();
}
}
}
接口没有构造方法,所以接口中的成员内部类可以直接通过外部接口名.内部类名进行对象的创建
局部内部类
-
当一个类定义在方法体内或者一个作用域内,那么这个类就叫局部内部类
public class Part { static{ //局部内部类 class A{ public void out(){ System.out.println("我是静态代码块中的局部内部类"); } } } public void Test(){ //局部内部类 class B{ public void out(){ System.out.println("我是方法里的局部内部类"); } } } }
局部内部类无法使用访问修饰符进行修饰,因为局部内部类的作用域仅在声明该类的块中。所有该类对外部世界可以完全的隐藏,即它的外部类中其他的模块也无法访问它。
局部内部类可以访问的外部类的成员根据所在方法体不同, 如果在静态方法中,可以访问外部类中所有静态成员,包含私有。如果在实例方法中,可以访问外部类中所有的成员,包含私有。局部内部类可以访问所在方法中定义的局部变量,但是要求局部变量必须使用final修饰。
public class Part { private int s = 1; { class A { final int s = 2; public void out() { System.out.println(s); System.out.println("我是代码块里的局部内部类"); } } } public void Test() { final int s = 3; //局部内部类 class B public void out() { Test(); System.out.println(s); System.out.println("我是方法里的局部内部类"); } } } public void Test() { System.out.println("外部类的普通方法"); } }
匿名内部类
-
使用new关键字初始化类对象时,不将实例保存在变量中则为匿名类
new String().length();
使用匿名类时,可以直接在该类后面.出自己想要的方法。
-
使用匿名内部类
-
new 接口名(){ //匿名内部类的类体部分};
public interface InterfaceTest { void test01(); void test02(); } class Test { public static void main(String[] args) { new InterfaceTest(){//创建匿名内部类 @Override public void test01() {//实现接口方法1 System.out.println("匿名内部类1"); } @Override public void test02() {//实现接口方法2 System.out.println("匿名内部类2"); } }.test01();//可以后面跟上需要调用的接口方法 } }
2.普通方法(new 接口名{//匿名内部类的类体部分});
public interface InterfaceTest {
void test01();
void test02();
}
class Test {
public static void main(String[] args) {
test(new InterfaceTest() {
@Override
public void test01() {
System.out.println("实现接口方法1");
}
@Override
public void test02() {
System.out.println("实现接口方法2");
}
});
}
public static void test(InterfaceTest interfaceTest){
interfaceTest.test01();
interfaceTest.test02();
}
}
3.接口类型 接口名 = new 接口类(){//匿名内部类的类体部分};
public interface InterfaceTest {
void test01();
void test02();
}
class Test {
public static void main(String[] args) {
InterfaceTest interfaceTest =new InterfaceTest() {
@Override
public void test01() {
System.out.println("实现接口方法1");
}
@Override
public void test02() {
System.out.println("实现接口方法2");
}
};
interfaceTest.test01();
}
}
匿名内部类是唯一一种没有构造器的类。正因为其没有构造器,所以匿名内部类的使用范围非常有限,大部分匿名内部类用于接口回调。匿名内部类在编译的时候由系统自动起名为Outter$1.class。一般来说,匿名内部类用于继承其他类或是实现接口,并不需要增加额外的方法,只是对继承方法的实现或是重写。
静态内部类
- 静态内部类也是定义在一个类里面,只不过使用static进行修饰,所以不依赖外部类。
- 它不能使用外部类的非static成员变量或者方法,因为在没有外部类的对象的情况下,可以创建静态内部类的对象,如果允许访问外部类的非static成员就会产生矛盾,因为外部类的非static成员必须依附于具体的对象
public class Outer {
//静态内部类
static class Inner {
private void in() {
System.out.println("这是静态内部类的方法");
}
}
}