内部类——详

本文详细介绍了Java中的内部类,包括成员内部类、局部内部类、匿名内部类以及静态内部类的用法和特性。通过示例代码展示了如何访问外部类的私有属性,以及内部类在不同场景下的应用,如接口实现和抽象方法。同时,讨论了内部类在类库设计中的作用,以及静态内部类和方法中定义的内部类的使用情况。最后,提到了匿名内部类在简化代码和实现接口快速创建子类时的便利性。
摘要由CSDN通过智能技术生成

内部类的基本概念

public class Demo{
    public static void main(String args[]){
        Outside out=new Outside();
        out.fun();
    }
}
class Outside{
    private String info="outside";
    public void fun(){
        Interior in=new Interior();
        in.print();
        System.out.println(in.info);//访问内部类的私有属性
    }
    class Interior{
        private String info="interior";
        public void print(){
            System.out.println(Outside.this.info);//访问外部类的私有属性
        }
    }
}

它破坏了程序的结构,但是他的优势是什么,如果没有就可以将类拿到外部:

public class Demo{
    public static void main(String args[]){
        Outside out=new Outside();//实例化外部类
        out.fun();
    }
}
class Outside{      //外部类
    private String info="outside";
    public String getInfo(){
        return info;
    }
    public void fun(){
        Interior in=new Interior(this);//实例化内部类对象
        in.print();//调用内部类
    }
    //思考一:如果不是必要,就不使用内部类,被类外部访问info需要有getter方法
}
class Interior{     //类中定义的内部类
    //思考三:如果想使用Outside类中的私有属性,需要用getter方法。实例化这个类时应该实例一个外部类的引用
    private Outside out;
    //思考四:通过interior类对象构造方法获取Outside类对象
    public Interior(Outside out){
        this.out=out;
    }
    public void print(){
        //思考二:调用外部类中的getter方法,需要实例化Outside类。但是主类中已经new了一个对象了,这里实例化第二个Outside不好
        System.out.println(this.out.getInfo());//调用外部属性
    }
}

那么他的作用:是为了可以很方便的访问外部类的私有属性。同时内部类也可以访问外部类的私有属性
……那为什么要定义分开的两个类?根据紧耦合松内聚的做法,在一个类中编写就好了吧?防止内容太多故意分开的?……骚操作?(嘀咕)

内部类的相关说明

生成.class文件时,内部类的格式为:
外部类.内部类 内部对象 =new 外部类().new 内部类()
内部类.class文件名:Outside$Interior.class( $ 在程序中会换成 . )
所以!

public class Demo{
    public static void main(String args[]){
        Outside.Interior in=new Outside().new Interior();
        in.print();
    }
}
class Outside{
    private String info="outside";
    class Interior{
        public void print(){
            System.out.println(Outside.this.info);//访问外部类的私有属性
        }
    }
}

如果此时Interior类只允许Outer类使用,就可以使用private修饰Interior类,进行私有定义:

class Outside{
    private String info="outside";
    private class Interior{
        public void print(){
            System.out.println(Outside.this.info);//访问外部类的私有属性
        }
    }
}

此时Interior类不允许外部使用。
那么同理,内部接口:

public class Demo{
    public static void main(String args[]){
        IChannel channel=new ChannelImpl();
        channel.send(((ChannelImpl)channel).new MessageImpl());
    }
}
interface IChannel{
    public void send(IMessage msg);
    interface IMessage{
        public String content();
    }
}
class ChannelImpl implements IChannel {
    public void send(IMessage msg){
        System.out.println("send Message:"+msg.content());
    }
    class MessageImpl implements IMessage{
        public String content(){
            return "MessageImpl";
        }
    }
}

内部抽象方法:

public class Demo{
    public static void main(String args[]){
        IChannel channel=new ChannelImpl();
        channel.send();
    }
}
interface IChannel{
    public void send();
    abstract class AMessage{
        public abstract String content();
    }
}
class ChannelImpl implements IChannel {
    public void send(){
        AMessage msg=new MessageImpl();
        System.out.println("send Message:"+msg.content());
    }
    class MessageImpl extends AMessage{
        public String content(){
            return "MessageImpl";
        }
    }
}

jdk1.8之后,接口中追加了static。那么,接口内部进行接口实现:

public class Demo{
    public static void main(String args[]){
        IChannel channel=IChannel.getChannelImpl();
        channel.send();
    }
}
interface IChannel{
    public void send();
    class ChannelImpl implements IChannel{
        public void send(){
            System.out.println("send message!");
        }
    }
    public static ChannelImpl getChannelImpl(){
        return new ChannelImpl();
    }
}

这在类库中会经常见到……

static定义内部类

如果用static定义内部类,内部类就变成了外部类
static内部类只能访问外部类中的static成员

class Outside{
    private static String info="outside";
    static class Interior{
        public void print(){
            System.out.println(Outside.info);//访问外部类的私有属性
        }
    }
}

此时Interior类是一个独立的类,要实例化Interior类,只需要“外部类.内部类()”例:Outside.Interior in=new Outside.Interior();

static内部定义接口属于一组相关定义。static内部接口出现形式较多。

public class Demo{
    public static void main(String args[]){
        IMessage.send(new MessageCollect(),new ChannelContect());
    }
}
interface IMessage{
    static interface IMessageCollect{
        public String getContent();
    }
    static interface IChannelContect{
        public boolean connect();
    }
    public static void send(IMessageCollect mc,IChannelContect cc){
        if(cc.connect()){
            System.out.println(mc.getContent());
        }else{
            System.out.println("connect fail");
        }
    }
}
class MessageCollect implements IMessage.IMessageCollect{
    public String getContent(){
        return "i am ok!";
    }
}
class ChannelContect implements IMessage.IChannelContect{
    public boolean connect(){
        return true;
        //return false;
    }
}

方法中定义内部类

内部类可以在任意结构中定义,包括:类中,方法中,代码块中。方法中定义内部类的形式较多。

public class Demo{
    public static void main(String args[]){
        new Outer().fun(20210101L);
    }
}
class Outer{
    private String msg="outer";
    public void fun(long time){
        class Inner{
            public void print(){
                System.out.println(Outer.this.msg);
                System.out.println(time);
                //方法中参数的直接访问是从jdk1.8开始支持的。jdk1.8之前若要访问,参数前必须追加final(fun(final long time)或final String str;)
                //这是为函数式编程准备的功能
            }
        }
        new Inner().print();
    }
}

匿名内部类

匿名内部类是简化的内部类,主要是在抽象类或接口的子类上实现的。(并不是只在抽象借口类中,只是在抽象接口中才有意义。)
匿名内部类的使用:

利用静态方法做一个匿名内部类

public class Demo{
    public static void main(String args[]){
        IMessage msg=new IMessage(){
            public void send(){
                System.out.println("send message");
            }
        };
        msg.send();
    }
}
interface IMessage{
    public void send();
}

在接口中直接定义匿名内部类

public class Demo{
    public static void main(String args[]){
        IMessage.getInstance().send();
    }
}
interface IMessage{
    public void send();
    public static IMessage getInstance(){
        return new IMessage(){
            public void send(){
                System.out.println("send");
            }
        };
    }
}

与内部类相比,匿名内部类只是一个没有名字的只能使用一次的,并且结构固定的子类操作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值