JAVA基础学习(九)--内部类

来源:互联网 发布:深蓝孩童知乎 编辑:程序博客网 时间:2024/04/30 04:24

一、内部类

 

1.1、内部类概念

定义在一个类内部中的另一个类,被称为内部类

特点:

可以直接访问,内部类的外部类中的,成员属性和方法(包含-private)

外部类要访问内部类中的成员和方法,需要先建立内部类对象

1.2、示例

 

复制代码
package com.day08.innerclass.demo1;/** * 包含内部类 * @author denny * */public class Outer { //外部类        //private成员    private String name="张三";    private int age=20;    private String gender="男";        /**     * 内部类     */    class Inner{        private int num=3;                public void hello(){            System.out.println("姓名:"+name+"年龄:"+age                    +"性别:"+gender);        }        public int getNum() {            return num;        }        public void setNum(int num) {            this.num = num;        }                    }                /*     * 外部类中的方法     */    public void show(){        System.out.println("姓名:"+this.name+"年龄:"+this.age                +"性别:"+this.gender);    }        /*     * 调用内部类     */    public void say(){        Inner inner=new Inner();        System.out.println("调用内部类:"+"num="+inner.getNum()+",  num="+inner.num);    }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public int getAge() {        return age;    }    public void setAge(int age) {        this.age = age;    }    public String getGender() {        return gender;    }    public void setGender(String gender) {        this.gender = gender;    }    }
复制代码

 

测试外部类

复制代码
package com.day08.innerclass.demo1;public class OuterTest {    public static void main(String[] args) {        //外部类调用内部类        Outer o=new Outer();        o.show();        o.say();    }}
复制代码

结果:

姓名:张三年龄:20性别:男
调用内部类:num=3, num=3

测试内部类

复制代码
package com.day08.innerclass.demo1;public class InnerTest1 {    public static void main(String[] args) {        // 声明内部类中对 象,先声明外部类,再声明内部类        Outer.Inner inner = new Outer().new Inner();        inner.hello();    }}
复制代码

姓名:张三年龄:20性别:男
调用内部类:num=3, num=3

1.3、静态内部类

如果内部类是static修饰的就只能调用父类中static成员

声明方式,可直接外部类.内部类()来声明或者调用

 

复制代码
package com.day08.innerclass.demo3;public class Outer {    //private成员        private String name="张三";        static int age=20;        private String gender="男";                /*         * 外部类中的方法         */        public void show(){            System.out.println("姓名:"+this.name+"年龄:"+this.age                    +"性别:"+this.gender);        }        /**         * 内部类         */        static class Inner{            private int num=3;                        public void hello(){                System.out.println("外部类年龄:"+age                        +",内部类属性"+this.num);            }            }        public static void main(String[] args) {            //静态内部类可以直接通过外部类.内部类声明            Outer.Inner inner=new Outer.Inner();            inner.hello();        }}
复制代码

 

外部类年龄:20,内部类属性3

1.4、内部类成员是static的话

这个内部类必须被static修饰,static只能调用外部类和内部类中的stiatic的成员.

 

复制代码
package com.day08.innerclass.demo3;public class Outer {    //private成员        private String name="张三";        static int age=20;        private String gender="男";                /*         * 外部类中的方法         */        public void show(){            System.out.println("姓名:"+this.name+"年龄:"+this.age                    +"性别:"+this.gender);        }        /**         * 内部类         */         static class Inner{            private  static int num=3;                        public static void hello(){                System.out.println("外部类年龄:"+age                        +",内部类属性"+num);            }            }        public static void main(String[] args) {            //静态内部类m成员也是静态的可以直接调用            Outer.Inner.hello();        }}
复制代码

 

结果:外部类年龄:20,内部类属性3

1.5、声明在外部类中成员方法中的内部类

声明成员方法中的,内部类,调用成员方法中的局部变量 时,成员方法中的局部变量 必须为final修饰

复制代码
package com.day08.innerclass.demo3;public class Outer {    // private成员    private String name = "张三";    static int age = 20;    private String gender = "男";    /*     * 外部类中的方法     */    public void show(int x) {        final int y = 5;        //System.out.println("姓名:" + this.name + "年龄:" + this.age + "性别:" + this.gender);        class Inner {            public void hello() {                System.out.println("hello-------"+x + " ," + y);            }        }        Inner inner = new Inner();        inner.hello();    }    /**     * 内部类     */    public static void main(String[] args) {        //声明成员方法中的,内部类,调用成员方法中的局部变量 时,成员方法中的局部变量 必须为final修饰        new Outer().show(8);    }}
复制代码

hello-------8 ,5

 

 

1.6、为什么内部类能直接访问外部类中的成员呢?

因为内部类持有了外部类的引用,外部类名.this。  (默认省略)
复制代码
package com.day08.innerclass.demo4;public class Outer {    private int num=3;        class Inner{        private int num=4;                public void show(){            int num=5;            //局部变量            System.out.println(num);            //内部类的成员变量            System.out.println(this.num);            //外部类的成员变量             System.out.println(Outer.this.num);        }    }    public static void main(String [] args){        new Outer().new Inner().show();    }}
复制代码

二、匿名内部类

2.1、匿名内部类概念 

内部类可以继承或实现一个外部类或者接口。

格式:
    new 外部类名或者接口名(){覆盖类或者接口中的代码,(也可以自定义内容。)}
    简单理解:
    就是建立一个带内容的外部类或者接口的子类匿名对象。
    什么时候使用匿名内部类呢?
    通常使用方法是接口类型参数,并且该接口中的方法不超过三个,可以将匿名内部类作为参数传递。
    好处:
    增强阅读性。

2.2、重写类中的方法

 

复制代码
package com.day08.innerclass.demo5;/** * 抽象类 * @author denny * */public abstract class Person {        private String name="张三";        public void show(){        System.out.println(this.name);            }    public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    }
复制代码

 

 

复制代码
package com.day08.innerclass.demo5;/** * 外部类 *  * @author denny 实现有一个方法的抽象类的匿名内部类 * */public class Outer {    private int num = 3;    public void say() {        new Person() {// 匿名内部类            public void show() {  //重写抽象类中的方法,抽象方法,普通方法都可以                System.out.println("..............." + num);            }        }.show(); //对象创建完成,调用自己    }    public static void main(String[] args) {        new Outer().say();    }}
复制代码

 

结果:

...............3

第二种写法,适后重写了多个方法

复制代码
package com.day08.innerclass.demo5;/** * 外部类 *  * @author denny 实现有一个方法的抽象类的匿名内部类 * */public class Outer {    private int num = 3;    public void say() {        Person person=new Person() {// 匿名内部类            public void show() {  //重写抽象类中的方法,抽象方法,普通方法都可以                System.out.println("..............." + num);            }        };        //对象创建完成        person.show();    }    public static void main(String[] args) {        new Outer().say();    }}
复制代码

2.3、示例使用接口的方式

复制代码
package com.day08.innerclass.demo6;/** * 接口 * @author denny * */public interface BirdPro {        /**     * 2个抽象方法     */    public void shout();        public void accact();}package com.day08.innerclass.demo6;public class Outer {    private String name="张三";        public void show(){        int y=3;        BirdPro birdPro=new BirdPro(){            //实现接口中的方法            @Override            public void shout() {                System.out.println(name+","+y);                            }            @Override            public void accact() {                System.out.println(y+","+name);                            }                                };        birdPro.shout();        birdPro.accact();    }        public String getName() {        return name;    }    public void setName(String name) {        this.name = name;    }    public static void main(String[] args) {        new Outer().show();    }}
复制代码

结果:

张三,3
3,张三

2.4、把匿名内部类做参数传递

  1. 通常的使用场景之一:
  2. 当函数参数是接口类型时,而且接口中的方法不超过三个。
  3. 可以用匿名内部类作为实际参数进行传递。

 

 

复制代码
package com.day08.innerclass.demo6;/** * 接口 *  * @author denny * */public interface BirdPro {    /**     * 2个抽象方法     */    public void shout();    public void accact();}
复制代码

 

复制代码
package com.day08.innerclass.demo6;class InnerDemo {    public static void main(String[] args) {        // 把接口做参数传递        show(new BirdPro() {            // 实现接口中的方法            @Override            public void shout() {                System.out.println("叫声");            }            @Override            public void accact() {                System.out.println("攻击");            }        });    }    public static void show(BirdPro birdPro) {// 做参数        // 调用        birdPro.accact();        birdPro.shout();    }}
复制代码

 

2.5、 初始化顺序

复制代码
package com.day08.innerclass.demo2;public class Fu {    int num = 9;    static{        System.out.println(" static Fu");    }    {        System.out.println("Fu");    }    Fu() {        super();// Object        // 显示初始化        // 构造代码块初始化        show(); // 构造函数调用方法,如果子类已经重写了,父类的方法,则执行子类的方法,但这时,成员还没有初初始化,所以为默认值    }    void show() {        System.out.println("fu show " + num);// 被覆盖,运行子类的    }}
复制代码
复制代码
package com.day08.innerclass.demo2;public class Zi extends Fu {    int num = 8;    static{        System.out.println(" static Zi");    }    {          System.out.println("Zi" );    }    Zi(){           super();           //显示初始化           //构造代码块初始化          show();    }     void show(){          System.out.println("zi show " + num);      }}
复制代码
复制代码
package com.day08.innerclass.demo2;public class Test1 {    public static void main(String[] args) {        new Zi();    }}
复制代码

结果:

static Fu static ZiFuzi show 0Zizi show 8

 


0 0
原创粉丝点击