Java 内部类(1): 基本语法
来源:互联网 发布:北京少儿编程培训班 编辑:程序博客网 时间:2024/06/12 22:15
可以将一个类的定义放在另一个类的内部,这就是内部类。内部类的表面意义一目了然,不过内部类的实现语法还是稍显繁琐。
内部类的分类
:内部类主要分为:普通内部类,匿名内部类,局部内部类,嵌套内部类(静态内部类)。
普通内部类
普通内部类内不能有静态成员变量和静态方法
public class Outer{ class Inner{ private String name; public Inner(String name){ this.name = name; } public void setName(String name){ this.name = name; } public String getName(){ return name; } } public Inner getInner(String name){ return new Inner(name); } public static void main(String[] args){ Outer out = new Outer(); Inner inner = out.getInner("inner"); System.out.println(inner.getName()); } }
普通内部类拥有对外部类的全部访问权,它能够与外部类进行通信并且可以操作外部类。当某个外部类对象创建了一个内部类对象,该内部类对象会秘密的保留一个指向创建它的外部类对象的引用。当内部类中访问外部类成员时,就是通过这个隐藏引用来拥有外部类的访问权。换句话说,内部类对象只能在与其外围类的对象关联的情况下才能创建(不包括静态内部类),构建内部类对象时,需要一个指向其外部类的引用,如果找不到这个引用,则编译器报错。
普通内部类不能含有静态成员变量和静态方法。
最典型的应用就是外部类有一个公共方法a,该方法返回一个内部类(该内部类是private的并且实现了某个公共接口,外部无法直接访问类,只能通过接口)对象的引用,也就是返回类型为公共接口类型
这样既可以得到一个公共接口的实现类,又完美隐藏了其实现细节,客户端不知道实现类的名字(因为该类是私有的,客户端无法访问),只能通过公共方法a得到它。java集合中的迭代器Iterator()就是其一。
例如:
//接口类public interface Selector { boolean end(); void next(); Object curr();}//主类public class Outer_3 { class SelectorImpl implements Selector { @Override public boolean end() { return false; } @Override public void next() { } @Override public Object curr() { return null; } } public Selector selector() { return new SelectorImpl(); } public static void main(String[] args) { Outer_3 outer3 = new Outer_3(); Selector selector = outer3.selector(); System.out.println(selector.end()); }}
匿名内部类
匿名内部类的使用基本上需要符合一下几点:
- 匿名内部类只能使用一次,创建匿名内部类的同时也会创建该类的一个对象,之后该类的定义消失。通常用来简化代码编写。
- 匿名内部类内部无法定义构造函数
- 匿名内部类不能有静态成员变量或静态方法
- 匿名内部类是局部内部类,所以局部内部类的限制匿名内部类也有
- 匿名内部类必须继承某个类或者实现某个接口(因为匿名,所以无法访问,要想使用只能通过向上转型为父类或者接口)
匿名内部类的典型应用是用来开启一个线程:
public class Main{ public static void main(String[] args){ Runnable r = new Runnable(){ public void run(){ System.out.println("new Tread is running"); } }; Thread thread = new Thread(r); thread.start(); }}
局部内部类:
//局部内部类public class Out_4 { public void inner(final String name) { //jdk8以下必须用final修饰,jdk8虽然不是必须,但是在类内部也是无法改变该变量的。 class Inner { private String sname; Inner(){ //name = name = ""; 编译错误,局部内类部无法改变方法参数 this.sname = name; } Out_4 getOut() { return Out_4.this; } } System.out.println(new Inner().sname); System.out.println(new Inner().getOut()); } public static void main(String[] args) { Out_4 out_4 = new Out_4(); out_4.inner("out_4"); //out_4.new Inner(); 在局部外部类所在的方法外部无法访问局部内部类 }}
嵌套内部类(静态内部类)
public class Out_5 { private int i; static private String j; public Out_5(int i,String jj){ this.i = i; j = jj; } public static void staticMethod(){ } static public class Inner { public int x; private int y; public Inner(int x,int y){ this.x = x; this.y = y; } public int getX(){ return x; } public int getY(){ return y; } public void print(){ System.out.println(j+":"+x+":"+y);; staticMethod();; //System.out.println(i); //静态内部类不能访问外部类的非静态成员 } } public static void main(String[] args) { Out_5.Inner inner = new Inner(1,2); Out_5.Inner inner1 = new Inner(3,4); inner.print(); //null:1:2 inner1.print(); //null:3:4 Out_5 out_5 = new Out_5(5,"10"); System.out.println(out_5.i+":"+out_5.j); //5:10 Out_5 out_ = new Out_5(5,"15"); System.out.println(out_.i+":"+out_.j); //5:15 inner.print(); 15:1:2 }}
静态内部类能够访问外部类的静态成员,除了创建时要在前面加上外部类名称.之外,跟普通静态类没什么区别。
静态内部类的特殊用途:接口内部的嵌套类。你放到接口中的类自动是public和static的,并不违反接口的语法。
通常情况下,接口内部不能放置任何代码,但如果你想要实现该接口的所有实现类共享一段公共代码,可以考虑在接口内定义静态类。
这有点类似于抽象类的非抽象方法。
//接口类ClassInInterfacepublic interface ClassInInterface { void f(); class Test{ //接口中的类自动是static,所以不需要额外加static private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } }}//接口实现类public class ClassInInterfaceImpl implements ClassInInterface { @Override public void f() { System.out.println("method f()"); } public static void main(String[] args) { ClassInInterfaceImpl instance = new ClassInInterfaceImpl(); Test test = new Test(); test.setName("name"); System.out.println(test.getName()); }}
new 和 this
非嵌套类情况下,内部类拥有对外部类的全部访问权,内部类内部拥有一条外部类的引用,那么如何在内部类中得到外部类的引用呢,这就是this的作用了。另外内部类的创建依赖于外部类的某个实例对象,如何由外部类对象创建一个内部类对象,这就需要用到new的新用法。示例如下
public Outer{ class Inner{ private String name; Inner(String name){ this.name = name; } public String getName(){ return this.name; } public Outer getOuter(){ //外部类名字.this return Outer.this; } } public static void main(String[] args){ Outer out = new Outer(); //外部对象.new 内部类构造器(匿名内部类无法用这种方式,但匿名内部类通用可以访问到外部类) Inner inner = out.new Inner("inner"); System.out.println(inner.getName()); Outer out2 = inner.getOuter(); System.out.println(out==out2); // true }}
- Java 内部类(1): 基本语法
- Java内部类语法
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- JAVA语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- Java语法总结 - 内部类
- 测试框架比较
- GetWindow、GetTopWindow和GetNextWindow(窗口句柄获取!!!)
- 数字金字塔
- Unity3d 生命周期所有实用方法极用法
- C#绘制的几种方法
- Java 内部类(1): 基本语法
- Delphi 中的 IfThen 函数
- 数据结构学习之链表的Java实现
- Clouder Manager: Yarn Fair scheduler config
- Java 判断字符串是否以什么开头
- Spring学习总结——Spring实现AOP的多种方式
- angular1资源
- I2C学习文章,看完即可秒懂
- easyui datagrid表格可以通过键盘上下箭头键来选择行