• java 内部类详解


    参考http://how2j.cn/k/interface-inheritance/interface-inheritance-inner-class/322.html#nowhere

    非静态内部类

    非静态内部类 BattleScore “战斗成绩”
    非静态内部类可以直接在一个类里面定义

    比如:
    战斗成绩只有在一个英雄对象存在的时候才有意义
    所以实例化BattleScore 的时候,必须建立在一个存在的英雄的基础上
    语法: new 外部类().new 内部类()
    作为Hero的非静态内部类,是可以直接访问外部类的private实例属性name的

    package charactor;
     
    public class Hero {
        private String name; // 姓名
     
        float hp; // 血量
     
        float armor; // 护甲
     
        int moveSpeed; // 移动速度
     
        // 非静态内部类,只有一个外部类对象存在的时候,才有意义
        // 战斗成绩只有在一个英雄对象存在的时候才有意义
        class BattleScore {
            int kill;
            int die;
            int assit;
     
            public void legendary() {
                if (kill >= 8)
                    System.out.println(name + "超神!");
                else
                    System.out.println(name + "尚未超神!");
            }
        }
     
        public static void main(String[] args) {
            Hero garen = new Hero();
            garen.name = "盖伦";
            // 实例化内部类
            // BattleScore对象只有在一个英雄对象存在的时候才有意义
            // 所以其实例化必须建立在一个外部类对象的基础之上
            BattleScore score = garen.new BattleScore();
            score.kill = 9;
            score.legendary();
        }
     
    }

    静态内部类

    在一个类里面声明一个静态内部类
    比如敌方水晶,当敌方水晶没有血的时候,己方所有英雄都取得胜利,而不只是某一个具体的英雄取得胜利。
    与非静态内部类不同,静态内部类水晶类的实例化 不需要一个外部类的实例为基础,可以直接实例化
    语法:new 外部类.静态内部类();
    因为没有一个外部类的实例,所以在静态内部类里面不可以访问外部类的实例属性和方法
    除了可以访问外部类的私有静态成员外,静态内部类和普通类没什么大的
    区别

    package charactor;
      
    public class Hero {
        public String name;
        protected float hp;
      
        private static void battleWin(){
            System.out.println("battle win");
        }
         
        //敌方的水晶
        static class EnemyCrystal{
            int hp=5000;
             
            //如果水晶的血量为0,则宣布胜利
            public void checkIfVictory(){
                if(hp==0){
                    Hero.battleWin();
                     
                    //静态内部类不能直接访问外部类的对象属性
                    System.out.println(name + " win this game");
                }
            }
        }
         
        public static void main(String[] args) {
            //实例化静态内部类
            Hero.EnemyCrystal crystal = new Hero.EnemyCrystal();
            crystal.checkIfVictory();
        }
      
    }

    匿名类

    匿名类指的是在声明一个类的同时实例化它,使代码更加简洁精练
    通常情况下,要使用一个接口或者抽象类,都必须创建一个子类

    有的时候,为了快速使用,直接实例化一个抽象类,并“当场”实现其抽象方法。
    既然实现了抽象方法,那么就是一个新的类,只是这个类,没有命名。
    这样的类,叫做匿名类
     另一篇匿名类讲解

    package charactor;
       
    public abstract class Hero {
        String name; //姓名
              
        float hp; //血量
              
        float armor; //护甲
              
        int moveSpeed; //移动速度
          
        public abstract void attack();
          
        public static void main(String[] args) {
              
            ADHero adh=new ADHero();
            //通过打印adh,可以看到adh这个对象属于ADHero类
            adh.attack();
            System.out.println(adh);
              
            Hero h = new Hero(){
                //当场实现attack方法
                public void attack() {
                    System.out.println("新的进攻手段");
                }
            };
            h.attack();
            //通过打印h,可以看到h这个对象属于Hero$1这么一个系统自动分配的类名
              
            System.out.println(h);
        }
          
    }

    本地类

    本地类可以理解为有名字的匿名类 
    与内部类不一样的是,内部类必须声明在成员的位置,即与属性和方法平等的位置。 
    本地类和匿名类一样,直接声明在代码块里面,可以是主方法,for循环里等等地方

    package charactor;
       
    public abstract class Hero {
        String name; //姓名
              
        float hp; //血量
              
        float armor; //护甲
              
        int moveSpeed; //移动速度
          
        public abstract void attack();
          
        public static void main(String[] args) {
              
            //与匿名类的区别在于,本地类有了自定义的类名
            class SomeHero extends Hero{
                public void attack() {
                    System.out.println( name+ " 新的进攻手段");
                }
            }
             
            SomeHero h  =new SomeHero();
            h.name ="地卜师";
            h.attack();
        }
          
    }

    在匿名类中使用外部的局部变量

    在匿名类中使用外部的局部变量,外部的局部变量必须修饰为final

    为什么要声明为final,其机制比较复杂,请参考第二个Hero代码中的解释

    注:在jdk8中,已经不需要强制修饰成final了,如果没有写final,不会报错,因为编译器偷偷的帮你加上了看不见的final

     Hero.java代码

    package charactor;
       
    public abstract class Hero {
     
        public abstract void attack();
          
        public static void main(String[] args) {
     
            //在匿名类中使用外部的局部变量,外部的局部变量必须修饰为final
            final int damage = 5;
             
            Hero h = new Hero(){
                public void attack() {
                    System.out.printf("新的进攻手段,造成%d点伤害",damage );
                }
            };
     
        }
          
    }

    abstract Hero代码

    package charactor;
       
    public abstract class Hero {
     
        public abstract void attack();
          
        public static void main(String[] args) {
     
            //在匿名类中使用外部的局部变量damage 必须修饰为final
            int damage = 5;
             
            //这里使用本地类AnonymousHero来模拟匿名类的隐藏属性机制
             
            //事实上的匿名类,会在匿名类里声明一个damage属性,并且使用构造方法初始化该属性的值
            //在attack中使用的damage,真正使用的是这个内部damage,而非外部damage
             
            //假设外部属性不需要声明为final
            //那么在attack中修改damage的值,就会被暗示为修改了外部变量damage的值
             
            //但是他们俩是不同的变量,是不可能修改外部变量damage的
            //所以为了避免产生误导,外部的damage必须声明为final,"看上去"就不能修改了
            class AnonymousHero extends Hero{
                int damage;
                public AnonymousHero(int damage){
                    this.damage = damage;
                }
                public void attack() {
                    damage = 10;
                    System.out.printf("新的进攻手段,造成%d点伤害",this.damage );
                }
            }
             
            Hero h = new AnonymousHero(damage);
             
        }
          
    }
  • 相关阅读:
    SpingBoot myBatis neo4j整合项目案例
    GCC 优化选项 -O1 -O2 -O3 -OS 优先级,-FOMIT-FRAME-POINTER(O3的优化很小,只增加了几条优化而已)
    睡个好觉的 12 条军规(坚持固定睡眠时间表,这一条最重要)
    恐怕你确定自己喜欢做什么(如果一件事能让你沉浸其中、安住当下,过后又不令你后悔,那它就是你喜欢的事:时间就应该拿来赚钱或提升赚钱的能力)
    专家解读:缺芯少人的中国集成电路,亟待打破高校学科壁垒
    你们一定要搞清楚被迫加班和自己弄的差别(被动的人得关节炎,主动的人身体更棒了)
    Linux命令排查线上问题常用的几个
    NFS (网络文件系统)
    查看JVM运行时堆内存
    SQL查询速度
  • 原文地址:https://www.cnblogs.com/lijingran/p/9093192.html
Copyright © 2020-2023  润新知