12.内部类(二)

2.内部类相关说明

        在内部类的结构中,不仅内部类可以方便地访问外部类的私有成员,外部类也同样可以访问内部类的私有成员。内部类本身是一个独立的结构,这样在进行普通成员属性的访问时,为了明确地标记处属性是外部类所提供的,可以采用“外部类.this.属性”的形式进行标注。

范例:外部类访问内部类私有成员

package cn.kuiba.util;

class Outer{                                       //外部类
    private String msg="www.kuiba.cn";              //私有成员属性
    public void fun(){                              //普通方法
        Inner in=new Inner();                       //实例化内部对象
        in.print();                                 //调用内部类方法
        System.out.println(in.info);                //访问内部类的私有属性
    }
    class Inner{                                    //Inner内部类
        private String info="魁拔";                  //内部类私有成员
        public void print(){
            System.out.println(Outer.this.msg);     //Outer类中的私有成员属性
        }
    }
}
public class Main {
    public static void main(String args[]){
        Outer outer=new Outer();                    //实例化外部类对象
        outer.fun();                                //调用外部类中的方法
    }
}

执行结果

www.kuiba.cn(“in.print()”代码执行结果,外部类msg成员属性)
魁拔(“in.info”代码执行结果,内部类info成员属性)

          本程序在内部类中利用了Outer.this.msg的形式调用外部类中的私有成员属性,而外部类同样可以利用内部类的对象访问内部类私有成员。

        需要注意的是,虽然内部类被外部类包裹,但同样属于一个完整类,所以可以直接进行内部类对象实例化,采用如下语法格式:

外部类.内部类 内部类对象=new 外部类().new 内部类();

        在此语法格式中,要求必须先获得相应的外部类实例化对象后,才可以利用外部类的实例化对象进行内部类对象实例化操作。

提示:关于内部类的字节码文件名称。

        当进行内部类源代码编译后,读者会发现有一个Outer$Inner.class字节码文件,其中所使用的标识符"$"在程序中就会变成".",所以内部类的全称就是“外部类.内部类”,由于内部类与外部类之间可以直接进行私有成员的访问,就必须保证在实例化内部类对象前首先实例化外部类对象。

范例:实例化内部类对象

package cn.kuiba.util;

class Outer{                                       //外部类
    private String msg="www.kuiba.cn";              //私有成员属性
        class Inner{                                //Inner内部类
        public void print(){
            System.out.println(Outer.this.msg);     //Outer类中的私有成员属性
        }
    }
}
public class Main {
    public static void main(String args[]){
        Outer.Inner in=new  Outer().new Inner();   //实例化内部类对象
        in.print();                                //直接调用内部类中的方法
    }
}

执行结果

www.kuiba.cn

        本程序在外部实例化内部类对象,由于内部类有可能要进行外部类的私有成员访问,所以在实例化内部类对象之前一定要实例化外部类对象。

        如果一个内部类不希望被其他类使用,可以添加private关键字将其定义为私有内部类。private,protected定义类的结构只允许出现在内部类声明处。

        内部类也可以应用在接口和抽象类中,即内部接口或者内部抽象类。

interface IChannel{                                //外部接口
    public void send(IMessage msg);                //【抽象方法】发送消息
    interface IMessage{                            //内部接口
        public String getContent();                //【抽象方法】获取消息内容
    }
}
class ChannelImpl implements IChannel{             //外部接口实现子类
    @Override    
    public void send(IMessage msg){                //方法覆写
        System.out.println("发送消息:" + msg.getContent());
    }
    class MessageImpl implements IMessage{          //内部接口实现子类,不是必须实现
        public String getContent(){                //覆写方法
            return "www.kuiba.cn";
        }
    }
}
public class Main {
    public static void main(String args[]){
        IChannel channel=new ChannelImpl();        //实例化外部类接口对象
        //实例化内部类接口实例化对象前需要首先获取外部类实例化对象
        channel.send(((ChannelImpl)channel).new MessageImpl());
    }
}
程序执行结果:
发送消息:www.kuiba.cn

        本程序利用了内部类的形式定义了内部接口,并且分别为外部接口和内部接口定义了各自的子类。由于IMessage是内部接口,所以在定义MessageImpl子类的时候也采用了内部类的定义形式。

范例:在接口中定义内部抽象类

package cn.kuiba.util;

interface IChannel{                             //外部接口
    public void send();                         //【抽象方法】发送消息
    abstract class AbstractMessage{             //内部抽象类
        public abstract String getContent();    //【抽象方法】获取信息内容
    }
}
class ChannelImpl implements IChannel{          //外部接口实现子类
    class MessageImpl extends AbstractMessage{  //内部抽象类子类
        @Override
        public String getContent(){             //方法覆写
            return "www.kuiba.cn";
        }
    }
    @Override
    public void send(){                         //方法覆写
        AbstractMessage msg=new MessageImpl();  //实例化内部抽象类对象
        System.out.println(msg.getContent());   //调用方法
    }
}
public class Main {
    public static void main(String args[]){
        IChannel channel=new ChannelImpl();     //实例化外部接口对象
        channel.send();                         //消息发送
    }
}

程序执行结果:
www.kuiba.cn

        本程序在IChannel外部接口的内部定义了内部抽象类,在定义ChannelImpl子类的print()方法时,利用内部抽象类的子类为父类对象实例化,实现程序。

        在JDK1.8之后由于接口中可以定义static方法,这样就可以直接在接口中进行该接口子类的定义,并利用static方法返回此接口实例。

范例:接口子类定义为自身内部类

package cn.kuiba.util;

interface IChannel{                             //外部接口
    public void send();                         //发送消息
    class ChannelImpl implements IChannel{      //内部类实现本接口
        @Override
        public void send(){                     //方法覆写
            System.out.println("www.kuiba.cn");
        }
    }
    public static IChannel getInstance(){       //定义static方法获取本接口实例
        return new ChannelImpl();               //返回接口子类实例
    }
}
public class Main {
    public static void main(String args[]){
        IChannel channel= IChannel.getInstance();   //获取接口对象
        channel.send();                             //消息发送
    }
}


程序执行结果:
www.kuiba.cn

        本程序定义IChannel接口时直接在内部定义了其实现子类,同时为了方便用户获取接口实例,使用了static定义了一个静态方法,这样用户可以不关心子类的前提下直接使用接口对象。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值