练习一
public class Outer { class Inner{ //内部类Inner private int a; //int变量a private int getA(){ //获取a return a; } Inner(int a){ //有参构造函数初始化a this.a = a; } } public Inner getInner(int x) {//获取Inner对象 return new Inner(x); } public static void main(String[] args) { Outer outer= new Outer();//创建外部类对象 Inner inner = outer.getInner(100); //调用getInner获取内部类对象(通过有参构造函数初始化a值) System.out.println(inner.getA());//获取a并输出 } }如果需要生成对外部类对象的引用,可以使用外部类的名字后面紧跟圆点和this。这样产生的引用自动地具有正确的类型,这一点在编译期就被知晓并受到检查,因此没有任何运行时开销。
public class DotThis { void f(){ System.out.println("DotThis.f()"); } class Inner{ private DotThis getDotThis(){ return DotThis.this; //返回外部类的对象 } } public Inner getInner(){ return new Inner(); } public static void main(String[] args) { DotThis dotThis= new DotThis(); Inner inner = dotThis.getInner(); inner.getDotThis().f(); } }有时想要创建某个内部类的对象,必须在new表达式中提供对其他外部类对象的引用,这时需要使用.new语法。
public class DotNew { public class Inner{ public Inner(){ System.out.println("111"); } } public static void main(String[] args) { DotNew dotNew = new DotNew(); DotNew.Inner inner = new DotNew().new Inner(); } }如果在内部类定义为static,那么这个内部类就成了'外部类',因为static定义的都是独立于类的结构。注意:static定义的不管是类还是方法只能访问static成员。
class Other{ private static final String MSG ="HelloWorld"; static class Inner{ public void print(){ System.out.println(Other.MSG); } } } public class JavaDemo { public static void main(String[] args) { Other.Inner in = new Other.Inner(); in.print(); }//output HelloWorld }内部接口
/** * 外部接口 */ interface IMessageWarp{ /** * 内部接口 */ static interface IMessage{ /** * 获取内容方法(抽象) * @return */ public String getCount(); } /** * 内部接口 */ static interface IChannel{ public boolean connect(); } /** * send方法,判断connect返回值,true返回getCount false输出提示信息 * @param msg * @param channel */ public static void send(IMessage msg,IChannel channel){ if(channel.connect()){ System.out.println(msg.getCount()); }else{ System.out.println("消息通道未连接"); } } } /** * 实现IMessage(静态内部接口,实现方法 implements 外部接口.内部接口) */ class DefaultMessage implements IMessageWarp.IMessage{ @Override public String getCount(){ return "www.baidu.com"; } } /** * 实现IChannel(静态内部接口,实现方法 implements 外部接口.内部接口) */ class DefaultChannel implements IMessageWarp.IChannel{ @Override public boolean connect() { return true; } } public class JavaDemo { public static void main(String[] args) { /** * 调用外部接口的静态方法,传入实现类 */ IMessageWarp.send(new DefaultMessage(),new DefaultChannel()); } //output www.baidu.com }使用static定义的内部接口,主要是因为这些操作属于一组相关的定义,有了外部接口之后,可以更加明确的明确这些接口的主要功能。
129方法中定义内部类(内部类可以在任意的结构中进行定义,包括类,方法,代码块。在实际开发中,在方法中定义内部类的形式较多)
例(jdk1.8之后加入了Lambda 表达式,方法内部类可以直接访问方法参数和局部变量)
/** * 外部类 */ class Outer{ private String a = "www.baidu.com"; /** * fun方法 内含内部类和内部类实例化对象后调用print方法 * @param b */ public void fun(long b){ /** * 内部类 */ class Inner{ public void print(){ System.out.println(Outer.this.a); System.out.println(b); } } new Inner().print(); } } public class JavaDemo { public static void main(String[] args) { new Outer().fun(1233444L); } //output www.baidu.com //1233444 }例(jdk1.8之前的版本)
/** * 外部类 */ class Outer{ private String a = "www.baidu.com"; /** * fun方法 内含内部类和内部类实例化对象后调用print方法 * @param b */ public void fun( final long b){ final String x = "Helloworld"; /** * 内部类 */ class Inner{ public void print(){ System.out.println(Outer.this.a); System.out.println(b); System.out.println(x); } } new Inner().print(); } } public class JavaDemo { public static void main(String[] args) { new Outer().fun(1233444L); } //output www.baidu.com //1233444 //Helloworld }130 匿名内部类
匿名内部类是一个简化的内部类的处理形式,其主要是在抽象类和接口在子类上使用的形式。和内部类相比匿名内部类只是一个没有名字的只能使用一次,并且结构固定的子类操作。
例:
interface IMessage{ public void send(String str); } public class JavaDemo { public static void main(String[] args) { IMessage iMessage = new IMessage() { @Override public void send(String str) { System.out.println(str); } }; iMessage.send("HelloWorld"); } } interface IMessage{ public void send(String str); public static IMessage getInstance(){ return new IMessage() { @Override public void send(String str) { System.out.println(str); } }; } } public class JavaDemo { public static void main(String[] args) { IMessage iMessage = IMessage.getInstance(); iMessage.send("HelloWorld"); } }