内部类

当生成一个内部类对象的时候,此对象与制造他的外围对象有着一种关系,内部类对象可以访问其外围类对象的所有成员。

如何在外面创建内部类使用外部类的实例创建内部类还有一种就是直接使用函数返回内部类的实例

Outer outer=new Outer();
Outer.Inner inner=outer.new Inner();//多层内部类需要一级一级的访问

内部类中返回外部类的引用

public class Outer {
    void f(){};
    class Inner{
        public Outer test(){
            return Outer.this;
        }
    }
}

内部类可以使用private修饰,这时候只能外部类访问内部类,这种形式是有意义的,可以让内部类继承一个公共的接口并重写接口中的方法,在外部类由一个函数返回内部类,并且向上转型成他继承的接口。这种情况下任何扩展内部类的行为都是没有价值的,因为只能访问接口中存在的方法,这样对于外面完全隐藏了函数的实现

interface private_test{
    void func();
}

public class Outer {
    private class Inner implements private_test{
        @Override
        public void func() {
            System.out.println("我是私有内部类中的方法");
        }
    }
    public private_test content(){
        return new Inner();
    }

    public static void main(String[] args) {
        Outer outer=new Outer();
        private_test pt=outer.content();
        pt.func();
    }
}

局部内部类

方法中的内部类属于方法本身,外部类不可以直接访问。注意可以在函数中可以返回局部内部类的引用,这时候需要使用它的父类进行向上转型,这种情况下并不意味着函数执行完毕,局部内部类就会死亡。下面的例子很显然,函数返回后函数执行结束,但是局部内部类并没有死亡。

interface LocalInner{
    void print();
}

public class Outer2 {

    LocalInner f(){
        class Inner implements LocalInner{

            @Override
            public void print(){
                System.out.println("我是局部内部类,方法结束,我还没死");
            }
        }
        return new Inner();
    }

    public static void main(String[] args) throws InterruptedException {
        Outer2 outer2=new Outer2();
        LocalInner f = outer2.f();
        TimeUnit.MILLISECONDS.sleep(3000);
        f.print();
    }
}

匿名内部类首先要有一个接口,在函数中重新定义内部类,最后返回内部类的引用。

interface Content{
    void value();
}

public class Outer3 {
    public Content content(){
        return new Content(){
 @Override
public void value(){
 System.out.println("我是匿名内部类");
            }
        };
    }
    public static void main(String[] args) {
        Content conten= new Outer3().content();
        conten.value();
    }
}

上面实际上是下面代码的简化.

interface Content{
    void value();
}

public class Outer3 {
    class Mycontent implements Content{
        @Override
        public void value() {
            System.out.println("等价的形式");
        }
    }
    public Content content(){
        return new Mycontent();
    }
    public static void main(String[] args) {
        Content conten= new Outer3().content();
        conten.value();
    }
}

匿名内部类使用外部类的引用的时候必须使用final修饰(JDK8之前),即使现在不需要加了,只是系统自己给加上了。所以在匿名内部类中修改外部类是不允许的。下面这种情况就不行

 

 

局部内部类和匿名内部类很相似,唯一的区别就是局部内部类可以有自己的构造函数,所以在需要自己定义构造函数的地方需要使用局部内部类

 

 

 嵌套类:将内部类声明成static

 1)嵌套类的创建,不需要其外部类的对象。

2)不能从嵌套类对象的内部访问非静态的外围类对象。

3)没有this引用

 

public class Outer4 {
    static String string="hello";
    String string1="";        //不可使用
    static class Inner{
        Inner(){
            System.out.println(string);
            System.out.println("Inner class 的构造函数");
        }
    }

    public static void main(String[] args) {
        Inner inner=new Inner();             //不需要任何外围类的信息
    }
}

接口中的内部类,这种内部类直接是static的

public interface Outer5 {
    void howdy();
    class test implements Outer5{
        @Override
        public void howdy() {
            System.out.println("我是接口中的内部类");
        }
    }

    public static void main(String[] args) {
        new test().howdy();   //直接可以使用,不需要外围的类
    }
}

 

 

 内部类不可以被覆盖:

就是说类A继承类B,类B中有个内部类C,这时候在A中重新定义内部类C,这个内部类是不会被覆盖的。

 

在向上转型的时候,如果子类重写了父类的方法,这时候,父类调用的时候还是子类中已经重写的方法(public、protected修饰的,并且继承的时候函数的范围只能变大或者相同,不可以变小),由于private是私有的不能被重写,所以这里没有。

重写接口中的方法只能是public abstract修饰,继承接口并重写里面的方法时候修饰符只能是public,另外接口中只能定义常量,public static final,不能定义变量

 最后注意所有的类都会生成.class文件,包括内部类。

 

posted on 2019-03-16 17:20  认真的谁  阅读(149)  评论(0编辑  收藏  举报

导航