内部类

把一个类放在一个类内部定义,这个定义在其他类内部的类就被称为内部类。

1. 内部类作用如下:

  1)内部类提供了更好的封装,把内部类应藏在外部类之内,不允许同一个包内的其他类访问该类。假设该类在脱离了某个类之外没有任何意义,可以将该类定义在依赖的类里。

  2)内部类成员可以直接访问外部的私有数据,因为内部类被当成外部类的成员,同一个类的成员之间可以互相访问。

  3)匿名内部类适合用于创建那些仅需要一次使用的类。

2. 非静态内部类:

  先创建外部类对象,再通过外部类对象创建内部类。Java不允许在非静态内部类重定义静态成员,静态方法,也不能有静态初始化块。

public class OutClass {
    private String a;
    private static String name;
    public void f(){}
    public static void fn(){}
    class InClass{
        private String b;
        public InClass(){
            b=a;
            b=name;
            f();
            fn();
        }
    }
    public static void main(String[] args) {
        OutClass.InClass inClass = new OutClass().new InClass();
    }
}

 

3. 静态内部类:
  如果用static来修饰一个内部类,它就属于这个外部类本身,而不属于某个外部类实例。根据静态成员不能访问非静态成员原则,静态内部类也不能访问外部类的非静态成员。

public class OutClass {
    private int a; private static String name; public OutClass(){} public void f() {} public static void fn(){} public static class InClass{ private int b; private static String c; public InClass(){ //b=a; //不能访问外部类的非静态变量 c=name; //f(); //不能使用外部类的非静态方法  fn(); } } public static void main(String[] args) { OutClass.InClass inClass =new InClass(); } }

4.接口内部类:

  接口内部类默认使用public staic修饰符。

5. 局部内部类:

  如果把一个内部类放在方法里定义,这个类就是一个局部内部类。对于局部成员,使用static修饰毫无意义,所以局部内部类不能用static修饰

public class Test {
    public static void main(String[] args) {
        abstract class InnerBase{
           int a;
           public abstract void fn();
        }
        class Inner extends InnerBase{
            public  void fn(){}
        }
        InnerBase inner = new Inner();
    }

}

6.匿名内部类
  匿名类适合创建那种只需要一次使用的类。你明年内部类必须集成一个父类或实现一个接口。必须实现父类或接口的所有抽象方法。

  如果匿名内部类想要访问外部类的变量,则必须使用final修饰符来修饰外部类的局部变量。

public class Test {
    interface Product{
        public String getName();
    }
    public abstract class Pro{
        public abstract void printName();
    }
    public static void main(String[] args) {
        System.out.println(new Product(){
                {
                    System.out.println("实现接口的匿名内部类初始化!");
                }
                public String getName(){
                    return "computer";
                }
            }.getName());
        
        final String nameString = "Keyboard";
        new Test().new Pro(){
                {
                    System.out.println("继承类的匿名内部类初始化!");
                }
                public void printName(){
                    System.out.println(nameString);;
                }
            }.printName();      
    }
}

 7.闭包和回调:

闭包是一种能被调用的对象,它保存了创建它的作用域信息。非静态内部类不仅记录了外部类的详细信息,还保留了一个创建非静态内部类对象引用,还可直接调用外部类的private成员,因此可以把非静态内部类当成面向对象领域的闭包。

以下代码为实际应用:

public class test {
    public abstract class Teachable{
        abstract void work();
    }
    public class Programmer{    
        public void work(){
            System.out.println("coding");
        }
    }
    public class TeachableProgrammer extends Programmer{
        private void teach() {
            System.out.println("teaching");
            
        }
        private class Closure extends Teachable{

            @Override
            public void work() {
                teach();
            }            
        }
        
        public Teachable getCallBackReference(){
            return new Closure();
        }
    }
    public static void main(String[] args) {
        TeachableProgrammer tProgrammer = new test().new TeachableProgrammer();
        tProgrammer.work();
        tProgrammer.getCallBackReference().work();
        
    }
}

 

以上内容来自学习《疯狂JAVA讲义》

转载于:https://www.cnblogs.com/wxlovewx/p/5231215.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值