zoukankan      html  css  js  c++  java
  • 基础学习day09--内部类

    一、内部类

    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 Zi
    Fu
    zi show 0
    Zi
    zi show 8

     

  • 相关阅读:
    MySQL视图更新
    JavaScript经典作用域问题
    进程间通信的几种方式
    Vue(MVVM)、React(MVVM)、Angular(MVC)对比
    CDN(Content Delivery Network)技术原理概要
    单点登录实现原理(SSO)
    composer 实现自动加载原理
    PHP 反射的简单使用
    php7安装php-redis扩展
    Git 简单入门(二)
  • 原文地址:https://www.cnblogs.com/liunanjava/p/4800707.html
Copyright © 2011-2022 走看看