• Java的内部类


    可以将一个类的定义放在另一个类的 定义内部,这就是内部类。

    1、使用.this和.new

    如果需要生成对外部类对象的引用,就可以使用外部类的名字后面紧跟着.this

    public class Inn {
        void print() {
            System.out.print("Inn.print()");
        }
        public class F1{
            public Inn dothis(){
                return Inn.this;
            }
        }
        public F1 f1() {return new F1();}
        public static void main(String[] args) {
            Inn inn = new Inn();
            Inn.F1 f1 = inn.f1();
            f1.dothis().print();
        }
    }

    一个Inn类中有一个print()方法,一个内部类F1,一个会返回F1对象的f1()方法,

    F1类中有一个将返回Inn对象的dothis()方法。

    main方法中先实例化一个Inn对象inn,然后调用Inn中的f1()方法生成一个F1的对象,f1.dothis就可以得到一个Inn对象并调用其中的输出方法f().

    上一个例子中,想要获得一个内部类F1的对象,就必须先创建一个外部类Inn的对象,,这是因为内部类对象会暗暗的连接到外部类的对象上,除非定义的是静态内部类。

    然后同样上一个例子中,想要获得一个内部类F1的对象,除了必须要先创建一个外部类Inn的对象以为,还需要再调用Inn中的方法来获得这个F1内部类对象。

        public static void main(String[] args) {
            Inn inn = new Inn();
            Inn.F1 f1 = new inn.F1();//这是错的
            f1.dothis().print();
        }

    这样会编译出错,应该使用.new,

        public static void main(String[] args) {
            Inn inn = new Inn();
            Inn.F1 f1 = inn.new F1();
            f1.dothis().print();
        }

    2、匿名内部类

    在java中匿名内部类的创建需要实现抽象类或者接口所以得先创建一个抽象类或者接口

    public class Inn {
         interface F {
            int i = 11;
            int value();
        }
        
        public F f(){
            return new F() {
                public int value() {return i;}
            };
        }
    public static void main(String[] args) { Inn inn = new Inn(); F f = inn.f(); System.out.println(f.value()); } }

    这里的Inn类中有一个F接口和一个f()方法,f()方法将返回值和这个返回值的生成和表示这个返回值的类的定义结合在一起了,然后这个类是没有名字的。

    这个语法是下面这个形式的简化形式

    public class Inn {
        
         interface F {
            int i = 11;
            int value();
        }
        
        public class F1 implements F{
            public int value() {return i;}
        }
        
        public F1 f() {return new F1();}
        
        public static void main(String[] args) {
            Inn inn = new Inn();
            F f = inn.f();
            System.out.println(f.value());
        }
    }

    这里新建了一个F1的类,这个F1类就是刚刚的那个匿名的内部类,

    带参数的匿名内部类,这样实现:

    public class Inn {
        
        abstract class  F {
            public F(int i) {
            }
            abstract int value();
        }
        
        public F f(int i){
            return new F(i) {
                public int value() {return i;}
            };
        }
        
        public static void main(String[] args) {
            int i = 2;
            Inn inn = new Inn();
            F f = inn.f(i);
            System.out.println(f.value());
        }
    }

    匿名抽象类由于没有名字,所以它没有构造函数,它的构造函数来自于它的父类也就是,因为接口是没有构造器的所以要使用抽象类。

    3、嵌套类

    将内部类声明为static的通常称为嵌套类,普通的内部类对象隐式的保存了一个引用,指向创建它的外围类对象,但是内部类是static的时候就是不是这样的了,所以嵌套类意味着:

    a、要创建嵌套类,将不需要其外围类的对象

    b、不能从嵌套类的对象中访问非静态的外围类对象

    c、普通内部类的字段与方法,自能放在类的外部层次上,所以普通内部类不能有static数据和static字段,也不能包含嵌套类,但是嵌套类能够包含这些东西

    d、嵌套类可以放在接口中作为接口的一部分,因为接口的任何类都是自动public和static 的,因为类是static的,只是将嵌套类置于接口的命名空间内而已,你甚至可以在内部类中实现外部接口。

    4、如果创建了一个内部类,然后继承其外围类并重新定义此内部类的时候:

    public class Inn {
        private F1 f;
        protected class F1{
                public F1() {
                    System.out.println("f1()");
                }
        }
        
        public Inn() {
            System.out.println("Inn()");
            f = new F1();
        }
    }
    class F2 extends Inn{
        public class F1{
            public F1() {
                System.out.println("f2()");
            }
        }
        
        public static void main(String[] args) {
            new F2();
        }
    }

    输出结果为:

    Inn()
    f1()

    这个例子说明,当继承了某个外围类的时候,内部类并没有发生什么神奇的变化,父类的内部类和子类的内部类是两个完全独立的实体,各自处在自己的命名空间内。

    public class Inn {
        private F1 f;
        protected class F1{
                public F1() {
                    System.out.println("f1()");
                }
        }
        
        public Inn() {
            System.out.println("Inn()");
            f = new F1();
        }
    }
    class F2 extends Inn{
        public class F1{
            public F1() {
                System.out.println("f2()");
            }
        }
        
        public static void main(String[] args) {
            F2 test1 = new F2();
           F2.F1 test2 = test1.new F1();
        }
    }

    这样的输出就是:

    Inn()
    f1()
    f2()

    如果想要明确的继承内部类就需要这样:

    public class Inn {
        private F1 f;
        protected class F1{
                public F1() {
                    System.out.println("f1()");
                }
        }
        
        public Inn() {
            System.out.println("Inn()");
            f = new F1();
        }
    }
    class F2 extends Inn{
        
        public class F1 extends Inn.F1{
            public F1() {
                System.out.println("f2()");
            }
        }
        private F1 f;
        public F2() {
            System.out.println("F2()");
            F1 f = new F1();
        }
        
        public static void main(String[] args) {
            F2 test1 = new F2();
            F2.F1 test2 = test1.new F1();
        }
    }

    输出结果为:

    Inn()
    f1()
    F2()
    f1()
    f2()
    f1()
    f2()

    5、局部内部类

    局部内部类就是定义在代码块中的内部类,典型的局部内部类是在一个方法体里面创建,这样的局部内部类不是外围类的一部分,但是它能访问当前代码块中的常量和外围类的所有成员。

    interface Counter{
        int next();
    }
    public class Inn {
        private int count = 0;
        
        Counter getCounter(final String name) {
            class localCounter implements Counter{
                public localCounter() {
                    System.out.println("localCounter()");
                }
                public int next() {
                    System.out.print(name + ",");
                    return count += 1 ;
                }
            }
            return new localCounter();
        }
        
        Counter getCounter2(final String name) {
            class localCounter implements Counter{
                public localCounter() {
                    System.out.println("localCounter()");
                }
                public int next() {
                    System.out.print(name + ",");
                    return count += 1;
                }
            }
            return new localCounter();
        }
        public static void main(String[] args) {
            Inn inn = new Inn();
            Counter
                c1 = inn.getCounter("x1"),
                c2 = inn.getCounter2("x2");
            System.out.println(c1.next());
            System.out.println(c2.next());
        }
    }

    输出:

    localCounter()
    localCounter()
    x1,1
    x2,2

    这里有两个方法,都同样返回一个Counter类对象,每个方法中的类中都有一个访问外围类的count的next方法。

    来源:
    
    think in java
    

      

  • 相关阅读:
    C#打开SDE数据库的几种方式
    关于DataGridView
    细说Sql Server中的视图(下)转载
    细说Sql Server中的视图(上)转载
    细说Sql Server中的视图
    Ajax实现原理,代码封装
    无限级下拉菜单(树形菜单,二级菜单)
    无限循环轮播图之JS部分(原生JS)
    无限循环轮播图之结构布局(原生JS)
    无限循环轮播图之运动框架(原生JS)
  • 原文地址:https://www.cnblogs.com/xxbbtt/p/7629864.html
Copyright © 2020-2023  润新知