java内部类的定义,java与javase
00-1010内部类1。内部类介绍2。非静态内部类3。静态内部类4。匿名内部类的摘要
目录
00-1010 (1)内部类提供了更好的封装。它可以将内部类隐藏在外部类中,同一包中的其他类不允许访问该类。
(2)内部类的成员可以直接访问外部类的私有数据,因为内部类被当作它的外部类成员,同一个类的成员可以互相访问。但是,外部类不能访问内部类的实现细节,比如内部类的成员变量。
(3)匿名内部类适合创建那些只需要使用一次的。
(4)在java中,内部类主要分为成员内部类(非静态内部类、静态内部类)、匿名内部类和局部内部类。
00-1010成员内部类是一种类似于字段、方法、构造函数、初始化块的类成员。成员内部类有两种类型:静态内部类和非静态内部类。用static修饰的成员内部类是静态内部类,没有用static修饰的成员内部类是非静态内部类。
因为内部类是其外部类的成员,所以它可以用任何访问控制字符来修饰,例如private、protected和public。非静态内部类不能有静态方法、静态属性和静态初始化块;非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类的成员;外部类的静态方法和静态代码块不能直接创建非静态的内部类实例和访问内部类成员;非静态内部类对象必须在外部类对象中注册,所以在创建非静态内部类对象之前,必须先创建它们的外部类对象;在非静态内部类的方法中访问变量时,系统首先查找方法中是否存在该名称的局部变量,如果有,则使用该变量。如果不存在,找出方法所在的内部类中是否有这个名称的成员变量,如果有,使用该成员变量;如果不存在,查找内部类所在的外部类中是否有此名称的成员变量,如果有,使用成员变量;如果仍然不存在,会出现编译错误:找不到变量。
(1)非静态内部类可以直接访问外部类的成员,但是外部类不能直接访问非静态内部类的成员。
public class outer class { private int a;Public void test(){ //编译报告错误,因为外部类无法直接访问非静态内部类成员system . out . println(b);//要访问内部类的实例字段,需要显式创建内部类对象inner class inner=new inner class();system . out . println(inner . b);}//定义一个非静态内部类,使用私有修饰符@ dataprivateclass inner class { private int b;Public void info(){ //在非静态内部类中,可以直接访问外部类的私有成员system . out . println(a);} }}(2)非静态内部类不能有静态方法、静态属性和静态初始化块。
class public outer class {//外部类字段private int a;//定义一个非静态的内部类,使用private修饰符@Data private class InnerClass{ //内部类字段private int b;私有int c;//编译错误,非静态内部类中不能有静态属性private static int d;//编译错误,不能有静态代码块static {System.out.println(非静态内部类中不能有静态代码块);}//编译错误,不能有静态方法public static void show(){ system . out . println(非静态内部类不能有静态方法);} }}(3)在外部类的静态方法和静态代码块中,不能直接创建非静态的内部类实例和访问内部类成员。
public class outer class { private int a;公共静态空的测试(){ //编译报错,外部类的静态方法中无法创建内部类实例inner class inner class=new inner class();}静态{
// 编译报错,外部类的静态方法中无法创建内部类实例 InnerClass innerClass = new InnerClass(); } // 定义非静态内部类 @Data private class InnerClass{ private int b; }}在外部类的普通方法和静态方法中访问内部类成员
public class OuterClass { private int a; // 定义非静态内部类,使用private修饰符 @Data private class InnerClass{ private int b; public void info(){ System.out.println("内部类的方法info()"); } } // 外部类的代码块 { InnerClass innerClass = new InnerClass(); innerClass.info(); } // 外部类的静态代码块 static { OuterClass.InnerClass inner = new OuterClass().new InnerClass(); inner.info(); } // 外部类的普通方法 public void test(){ // 在外部类里使用非静态内部类时,与平时使用普通类并没有太大的区别 InnerClass inner = new InnerClass(); // 访问内部类的Filed System.out.println(inner.b); // 访问内部类的方法 inner.info(); } // 外部类的静态方法 public static void test1(){ // 外部类的静态方法、静态代码块中不能直接创建非静态内部类实例 OuterClass.InnerClass inner = new OuterClass().new InnerClass(); // 访问内部类的Filed System.out.println(inner.b); // 访问内部类的方法 inner.info(); } // 测试 public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.test(); }}
3. 静态内部类
如果使用static来修饰一个内部类,则这个内部类就属于外部类本身,而不属于外部类的某个对象。static关键字的作用是把类的成员变成类相关,而不是实例相关,即static修饰的成员属于整个类,而不属于单个对象。
静态内部类可以包含静态成员,也可以包含非静态成员。静态内部类不能访问外部类的实例成员,只能访问外部类的类成员;外部类不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。(1) 静态内部类不能访问外部类的实例成员,只能访问外部类的类成员
public class OuterClass { private int a; private static int b; public void test(){ System.out.println(a); } @Data private static class InnerClass{ private int c; // 静态内部类中可以包括静态成员 private static int d; public void info(){ // 编译报错,静态内部类不能访问外部类的实例成员 System.out.println(a); } public static void show(){ // 静态内部类可以访问外部类的静态成员 System.out.println(b); } }}
(2) 外部类不能直接访问静态内部类的成员,但可以使用静态内部类的类名作为调用者来访问静态内部类的类成员,也可以使用静态内部类对象作为调用者来访问静态内部类的实例成员。
public class OuterClass { private int a; private static int b; public void test(){ // 外部类不能直接访问静态内部类的成员 // 可以使用静态内部类对象作为调用者来访问静态内部类的实例成员 InnerClass innerClass = new InnerClass(); innerClass.show(); // 可以使用静态内部类的类名作为调用者来访问静态内部类的类成员 InnerClass.show(); } public static void main(String[] args) { OuterClass outerClass = new OuterClass(); outerClass.test(); } @Data private static class InnerClass{ private int c; private static int d; public static void show(){ System.out.println(b); } }}
4. 匿名内部类
匿名内部类适合创建那种只需要一次使用的类,创建匿名内部类时会立即创建一个该类的实例,这个类定义立即消失,匿名内部类不能重复使用。
匿名内部类必须继承一个父类,或实现一个接口,但最多只能继承一个父类,或实现一个接口;匿名内部类不能是抽象类,因为系统在创建匿名内部类时,会立即创建匿名内部类的对象。因此不允许将匿名内部类定义成抽象类;匿名内部类不能定义构造器,因为匿名内部类没有类名,所以无法定义构造器,但匿名内部类可以定义实例初始化块,通过实例初始化块来完成构造器需要完成的事情;
public interface Product { public int getPrice(); public String getName();}
public class Test { public void test(Product product){ System.out.println("name:"+product.getName() +"-------"+"name:"+product.getPrice()); } public static void main(String[] args) { Test test = new Test(); test.test(new Product() { @Override public int getPrice() { return 12; } @Override public String getName() { return "苹果"; } }); }}
Test类定义了一个test方法,该方法需要一个Product对象作为参数,但Product只是一个接口,无法直接创建对象,因此此处考虑创建一个Product接口实现类的对象传入该方法——如果这个Product接口实现类需要重复使用,则应该将该实现类定义成一个独立类;如果这个Product接口实现类只需一次使用,则可采用上面程序中的方式,定义一个匿名内部类。
总结
本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注盛行IT的更多内容!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。