【Java学习笔记】28:再谈四种内部类

来源:互联网 发布:团购网站 淘宝折扣 编辑:程序博客网 时间:2024/05/22 12:16

内部类又叫嵌套类,是在类的体内再定义的类。
[1].成员内部类
也叫属性内部类。
它可以当成外部类的成员来看待,所以可以直接访问外部类的所有成员(属性和方法),即使这成员时私有的或者静态的。
外部类要访问内部类的成员时,则需要实例化内部类的对象。可以知道成员内部类不能含有static的变量的方法,但是可以有static常量。

package day28;public class Test {    public static void main(String[] args) {        Outer outer=new Outer();//先创建一个外部类对象        Outer.Inner inner=outer.getInner();//用外部类对象自写的getInner()方法        outer.b=100;        outer.m2();        inner.a2=100;        inner.x2();    }}//外部类class Outer{    private int a;    public int b;    static int c;    private void m1(){    }    //外部类中如要访问成员内部类的成员,需对内部类实例化    public void m2(){        Outer.Inner inner=new Outer.Inner();        inner.a1=1;        inner.a2=2;        inner.x1();        inner.x2();    }    static void m3(){    }    //常定义这种方法来使外部类访问内部类,这样外部类内部类就都有了    public Inner getInner(){        return new Inner();    }    //成员内部类    class Inner{        private int a1;        public int a2;        static final int a3=1;//可以有这样静态的常量,但是不可以有变量        //成员内部类可以访问外部类的任何成员        private void x1(){            a=1;            b=2;            c=3;            m1();            m2();            m3();        }        public void x2(){        }    }}

看一下编译后生成的class文件:
这里写图片描述

[2].静态内部类(常用)
我们知道静态成员不需要实例化,可以通过类名称直接访问。
静态内部类也很类似,不需要实例化外部类就可以访问静态内部类,而且它里面的成员是允许有static关键字的。
静态内部类中的方法常常设置成public方便被调用。

package day28;public class Test {    public static void main(String[] args) {        Outer.Inner.a=100;//直接访问属性        Outer.Inner.m2();//直接调用方法        //例子测试        int[] a={2,8,19,-7,5,9,16,-3,6,1,0,16};        MaxMin.Pair pair=MaxMin.Pair.getMinMax(a);        System.out.println(pair.max);        System.out.println(pair.min);    }}//外部类class Outer{    static int i;    static void m1(){    }    //静态内部类    static class Inner{        //可以有静态变量和方法        static int a;        static void m2(){        }    }}//例子class MaxMin{    //静态内部类    static class Pair{        static int min,max;        //获取数组中最大最小值        static Pair getMinMax(int[] a){            min=a[0];            max=a[0];            for(int x:a)            {                if(x<min)                    min=x;                if(x>max)                    max=x;            }            return new Pair(min,max);        }        //生成的两种构造方法        public Pair() {            super();        }        public Pair(int min, int max) {            super();            this.min = min;            this.max = max;        }        //生成的get和set方法        public int getMin() {            return min;        }        public void setMin(int min) {            this.min = min;        }        public int getMax() {            return max;        }        public void setMax(int max) {            this.max = max;        }    }}

运行结果:
19
-7

[3].局部内部类
就像定义一个局部变量一样,在某个代码块中也可以定义一个类,即是局部内部类。
但它很少见,所以只学习一下语法格式。

package day28;public class Test {    public static void main(String[] args) {        Outer outer=new Outer();        outer.m1();    }}//外部类class Outer{    int a=1;    int b=2;    public void m1(){        if(a<b)        {            //局部内部类(只在这个代码块中生效)            class Inner{                private int x;                public Inner(int x){                    this.x=x;                }                public void printA(){                    System.out.println(x);                }            }            Inner inner=new Inner(a);            inner.printA();        }        else        {            System.out.println(b);        }    }}

运行结果:
1
看一下它的class文件:
这里写图片描述

[4].匿名内部类(常用)
有时没必要把所有的接口和抽象类都实现一遍,就可以考虑用到匿名内部类。
比如下面这种方式,是常规的类实现接口以完成方法的方式。

package day28;public class Test {    public static void main(String[] args) {        Computer pc=new Computer();        pc.read();        pc.write();    }}//一个接口interface USB{    public void write();    public void read();}//类要实现这个接口class Computer implements USB{    @Override    public void write() {        System.out.println("writing...");    }    @Override    public void read() {        System.out.println("reading...");    }}

如果接口太多了而类不是必要,这样做就有些麻烦了,那么可以使用匿名内部类。

package day28;public class Test {    public static void main(String[] args) {        //接口不能实例化,这里是一个匿名内部类实现了接口的方法并创建了实例        USB usb=new USB(){            public void read(){                System.out.println("reading...");            }            public void write(){                System.out.println("writing...");            }        };        usb.read();        usb.write();    }}//一个接口interface USB{    public void write();    public void read();}

运行结果:
reading…
writing…

对于抽象类,也可以用匿名内部类去解决类似的问题。
首先是常规的类去继承抽象类以实现其抽象方法的方式如下。

package day28;public class Test {    public static void main(String[] args) {        Dogs dog=new Dogs();        dog.eat();        dog.sleep();    }}//一个抽象类abstract class Animal{    abstract void eat();    abstract void sleep();}//一个类去继承抽象类class Dogs extends Animal{    public void eat(){        System.out.println("dog eating...");    }    public void sleep(){        System.out.println("dog sleeping...");    }}

使用匿名内部类,可以像下面这样做。

package day28;public class Test {    public static void main(String[] args) {        Animal a=new Animal(){            public void eat(){                System.out.println("dog eating...");            }            public void sleep(){                System.out.println("dog sleeping...");            }        };        a.eat();        a.sleep();    }}//一个抽象类abstract class Animal{    abstract void eat();    abstract void sleep();}

运行结果:
dog eating…
dog sleeping…
看一下生成的class文件:
这里写图片描述

原创粉丝点击