内部类2

成员内部类:

说明:
  • 成员内部类是定义在外部类的成员位置,并且没有static修饰。
  1. 可以直接访问外部类的所有成员,包括私有的

  2. 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员

  3. 作用域 和外部类的其他成员一样,为整个类体、

    比如前面的案例,在外部类的成员方法中创建成员内部类对象,再调用方法

  4. 成员内部类–访问—>外部类成员(比如:属性) [访问方式:直接访问]

  5. 外部类–访问—>成员内部类 [访问方式:创建对象,再访问]

  6. 外部其他类–访问—>成员内部类

  • 法一:Outer08.Innter08 innter08 = outer08.new Innter08();

  • 法二:在外部类中,编写一个方法,可以返回Inner08对象

  1. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员) 去访问
    public class MemberInnerClass01{
        public static void main(String[] args) {
            Outer08 outer08 = new Innter08();
            outer08.t1();
            //外部其他类,使用成员内部类的两种方式:
            //其它外部类访问内部类,方式一:
            //outer08.new Innter08(); 相当于把new Innter08()当作是outer08成员
            Outer08.Innter08 innter08 = outer08.new Innter08();
            //方式二,在外部类中,编写一个方法,可以返回Inner08对象
            Outer08.Innter08 inner08Instance = outer08.getInnter08Instance();
            inner08Instance.say();
        }
    }
    class Outer08{  //外部类
        private double sal = 99.8;
        private int n1 = 10;
        public String name = "张三";

        private void hi(){
            System.out.print("hi()方法~~");
        }
        public class Innter08{  //成员内部类
            public void say(){
                //可以直接访问外部类的所有成员,包含私有的
                System.out.print("n1 = " + n1 + "name = " + name);
                hi();
            }
        }
        //方法,返回一个Inner08实例
        public Innter08 getInnter08Instance(){
            return new Innter08();
        }
    }
    public void t1(){
        //使用了成员内部类
        //创建成员内部类的对象,然后使用相关的方法
        Innter08 innter08 = new Innter08();
        innter08.say();
        System.out.print(innter08.sal);
    }

静态内部类:

说明:

静态内部类是定义在外部类的成员位置,并且有static修饰

  1. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员

  2. 可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员

  3. 作用域:同其他的成员,为整个类体

  4. 静态内部类–访问—>外部类(比如:静态属性) [访问方式:直接访问所有静态成员]

  5. 外部类–访问—>静态内部类 访问方式:创建对象,再访问

  6. 外部其他类–访问—>静态内部类

  • 法一:Outer08.Innter08 innter08 = outer08.new Innter08();

  • 法二:在外部类中,编写一个方法,可以返回Inner08对象

  1. 如果外部类和静态内部类的成员重名时,静态内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员) 去访问

    public class StaticInnerClass01{
        public static void main(String[] args) {
            Outer10 outer10 = new Outer10();
            outer10.m1();
        }   
    }
    
    class Outer02{  //外部类
        private int n1 = 10;
        private static String name = "张三";
        //inner10就是静态内部类
        /*
            1、放在外部类成员位置
            2、使用static修饰
            3、可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
            4、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员
            5、
        */
        pravite static class Inner10{
            public void say(){
                System.out.print(name);
            }
        }
        public void m1(){
            Inner10 inner10 = new Inner10();
            inner10.say();
        }
    }
    

枚举类:

引出:

要求创造季节(Season)对象,请设计并完成

        public class Enumeration01{
            public static void main(String[] args) {
                Season spring = new Season("春天","温暖");
                Season winter = new Season("冬天","寒冷");
                Season summer = new Season("夏天","炎热");
                Season autumn = new Season("秋天","凉爽");
                //因为对于季节而言,他的对象(具体值)是固定的四个,不会有更多
                //如果这样设计,不能提现季节是固定的,还可以创建其他对象
                //因此,这样的设计不好===>枚举类:把具体的对象一个一个列举出来的类
                //如:
                Season other = new Season("其他","其他");
            }
        }
        class Season{
            private String name;
            private String desc;    //描述
            //构造器
            //.getXX
            //.setXX
        }
分析:

创建Season对象有如下特点:

  • 季节的值是有限的几个值(spring、summer、autumn、winter)
  • 只读,不需要修改
解决方案——枚举:
  1. 枚举对应英文(enumeration,简写enum)
  2. 枚举是一组常量的集合
  3. 可以这样理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象
枚举的两种实现方式:
  1. 自定义类实现枚举
  2. 使用enum关键字实现枚举

自定义枚举类:

  1. 不需要提供setXX方法,因为枚举对象值通常为只读;
  2. 枚举对象/属性使用 final + static 共同修饰,实现底层优化;
  3. 枚举对象名通常使用全部大写,常量的命名规范
  4. 枚举对象根据需要,也可以有多个属性
演示自定义枚举
        class Season{
            private String name;
            private String desc;    //描述
            //3、在Season内部,直接创建固定的对象
            //使用static属性会导致Season类加载,可以加final修饰符
            public final static Season SPRING = new Season("春天","温暖");
            public final static Season WINTER = new Season("冬天","寒冷");
            public final static Season SUMMER = new Season("夏天","炎热");
            public final static Season AUTUMN = new Season("秋天","凉爽");
            //1、将构造器私有化,防止直接new
            private Season(……){
                ……
            }
            //.getXX
            //2、去掉setXX方法,防止属性被修改
        }
小结:
  1. 构造器私有化
  2. 本类内部创建一组对象(四个 春夏秋冬)
  3. 对外暴露对象(通过为对象添加 public final static修饰符)
  4. 可以提供get方法,但是不要提供set方法

enum枚举类:

演示使用enum关键字来实现枚举类

        //1、使用 enum 关键字来替代 class
        enum Season2{

/*          //在Season内部,直接创建固定的对象
            //使用static属性会导致Season类加载,可以加final修饰符
            public final static Season SPRING = new Season("春天","温暖");
            public final static Season WINTER = new Season("冬天","寒冷");
            public final static Season SUMMER = new Season("夏天","炎热");
            public final static Season AUTUMN = new Season("秋天","凉爽");*/

            //2、public final static Season SPRING = new Season("春天","温暖");
            //  直接使用 SPRING("春天","温暖");
            //即:常量名(实参列表)
            //3、如果有多个常量(对象),使用逗号间隔即可
            SPRING("春天","温暖"),WINTER("冬天","寒冷"),SUMMER("夏天","炎热"),AUTUMN("秋天","凉爽");
            //4、如果使用enum 来实现枚举,要求将定义常量对象写在最前面

            private String name;
            private String desc;    //描述
            //将构造器私有化,防止直接new
            private Season(……){
                ……
            }
            //.getXX
            //去掉setXX方法,防止属性被修改
  1. 使用 enum 关键字来替代 class

  2. “public final static Season SPRING = new Season(“春天”,”温暖”);” 直接使用 “SPRING(“春天”,”温暖”);”

    即:常量名(实参列表)

  3. 如果有多个常量(对象),使用逗号间隔即可

  4. 如果使用enum 来实现枚举,要求将定义常量对象写在最前面

注意事项:
  1. 当我们使用enum关键字开发一个枚举类时,默认会继承Enum类

  2. 传统的”public final static Season SPRING = new Season(“春天”,”温暖”);”

  • 简化成 “SPRING(“春天”,”温暖”);” ,这里必须知道,它调用的是哪个构造器

  • 从传入的实参可以看出来,比如上面调用的就是两个参数的构造器

  1. 如果使用无参构造器 创建 枚举对象,则实参列表和小括号都可以省略

  2. 当有多个枚举对象时,使用”,”间隔,最后有一个分号收尾

  3. 枚举对象必须放在枚举类的首行

enum常用方法说明:
说明:

使用关键字enum时,会隐式继承Enum类,这样我们就可以使用Enum类相关的方法

  1. toString:Enum类已经重写过了,返回的时是当前对象名,子类可以重写该方法,用于返回对象的属性信息
  2. name:返回当前对象名(常量名),子类中不能重写
  3. ordinal:返回当前对象的位置号,默认从0开始
  4. values:返回当前枚举类中的所有常量
  5. valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
  6. compareTo:比较两个枚举常量,比较的就是位置号!
演示Enum类的各种方法的使用,以Season2枚举类来演示各种方法
            public static void main(String[] args) {
                Season2 autumn = Season2.AUTUMN;
                System.out.print(autumn.name());
                /*
                    输出枚举对象的名字
                */
                System.out.print(autumn.ordinal());
                /*
                    输出结果:
                                3
                    输出的是该枚举对象的次序(编号),是从0开始的,枚举对象是第4个,所以输出3
                */
                Season2[] values = Season2.values();
                /*
                    含有定义的所有枚举对象
                */
                for (Season2 season :values ) { //增强for循环
                    //从values一次取一个放到season
                }
                //1、根据输入的"AUTUMN" 到 Season2的枚举对象去查找
                //2、如果找到了,就返回,如果没找到,就报错
                Season2 autumn1 = Season2.valuesOf("AUTUMN");
                System.out.print("autumn1=" + autumn1);
                /*
                    输出:
                        ture
                */
                //把 Season2.AUTUMN 枚举对象的编号 和 Season2.SUMMER枚举对象的编号比较
                //Season2.AUTUMN的编号(3) - Season2.SUMMER的编号(0)
                System.out.print(Season2.AUTUMN.compareTo(Season2.SUMMER));
                /*  
                    输出结果:
                                3
                */
            }
使用细节:
  1. 使用enum关键字后,就不能继承其他类了,因为enum会隐式继承Enum,而java是单继承机制;

  2. 枚举类和普通类一样,可以实现接口,如下形式:

                enum 类名 implements 接口1,接口2{}
                interface Iplaying{
                    public void playing();
                }
                enum Music implements Iplaying{
                    @Override
                    public void playing(){
                        System.out.print("播放音乐~~");
                    }
                }
    
创作不易!转载请注明作者及文章链接或作者博客链接——
- 作者:pidanxia
- 链接:https://pidanxia.ink
(链接可为:**文章链接**或者**作者博客链接**)
暂无评论

发送评论 编辑评论


				
上一篇
下一篇