资讯详情

java笔记-2

内部类

基本介绍

一类内部完全嵌套了另一类结构。嵌套类称为内部类(inner class),其他类型的嵌套被称为外部类别(outer class)。它是我们类的第五大成员属性、方法、结构、代码块、内部类。内部类最大的特点是可以直接访问私有属性,并反映类之间的包含关系。

基本语法2

class Outer{ //外部类

class Lnner{

}

}

class Other{ //外部其他类别

}

内部分类(4种)

在外部类的局部位置定义(如方法):

  1. 局部内部类(有类名)
  2. 匿名内部类(无类名,重点)

定义外部成员的位置:

  1. 成员内部类无用)static修饰)
  2. 静态内部类(使用static修饰)

使用局部内部类

说明:局部内部类定义为外部类的局部位置,如方法中的类名。

  1. 所有外部成员,包括私接访问,包括私人成员

  2. 访问修饰符不能添加,因为它的地位是局部变量。修饰符不能用于局部变量。但是可以使用final修改(使用后不会继承),因为局部变量也可以使用final

  3. 功能域:仅在定义它的方法或代码块中。

  4. 局部内部类-访问---->外部成员访问:直接访问

  5. 外部类----访问---->局部内部成员

    访问方法:在访问中创建对象(注:必须在作用域内)

  6. 外部其他类---->不能访问---->局部内部类(因为 局部内部类地位是一个局部变量)

  7. 如果外部和局部内部成员重名,默认遵循就近原则。如果你想访问外部成员,你可以使用它 (外部类名.this.访问成员)

    System.out.println(外部类n2” 外部类名.this.n2);

记住: (1)方法中/代码块定义局部内部类

(2)方法体或代码块中的作用域

(3)本质仍然是一个类

使用匿名内部类(重要!

注:匿名内部类定义为外部类的局部位置,如方法中没有类名

// 1.本质是类 (2)内部类 (3)这类没有名字 (4)同时是一个对象

  1. 匿名内部基本语法

    new 类或接口 (参数表){

    类体

    };

  2. 匿名内部语法很奇怪,因为匿名内部语法不仅是一个类的定义,也是一个对象。因此,从语法的角度来看,它不仅具有定义类的特征,还具有创建对象的特征。以前的代码分析可以看作是一个特征,因此可以调用匿名内部方法。

  3. 所有外部成员都可以直接访问,包括私人使用

  4. 访问修饰符不能添加,因为它的地位是局部变量。

  5. 作用域:仅在定义他的方法或代码块中。

  6. 匿名内部类-访问—>外部类成员 直接访问:直接访问

  7. 其他外部类-不能访问—>匿名内部类(因为 匿名内部地位是局部变量)

  8. 如果外部类和内部类重名,内部访问,默认遵循就近原则。如果你想访问外部成员,你可以使用它(外部名称.this.访问成员)

基于接口演示

/* 匿名内部类(基于接口)的演示 */ public class AnonymousInnerClass { 
             public static void main(String[] args) { 
                 Outer04 outer04 = new Outer04();         outer04.method();     } }  class Outer04{ 
         //外部类     private int n1 = 10; //属性     public void method() { 
                 ///基于接口的匿名内部类         /* 1.要求:要使用接口IA,并创建对象 2.传统方法,写一个类,实现界面,创建对象 3.需求是 Tiger 类只能用一次,以后不用了 4.匿名内部类可用于简化开发 5.tiger 编译类型是 IA 6.tiger 操作类型是 就是 匿名内部类 名为 Outer04$1 7.jdk底层创建匿名内部类别 Outer04$1.立即创建 Outer04$1实例, 并返回地址 tiger 8.匿名内部类使用一次,就不能再使用了 我们 */         IA tiger =  new IA() { 
        

            @Override
            public void cry() { 
        
                System.out.println("老虎");
            }
        };
        tiger.cry();
        System.out.println("tiger的运行类型=" + tiger.getClass());
// IA tiger = new Tiger();
// tiger.cry();
    }
}

interface IA{ 
         //接口
    public void cry();
}

//class Tiger implements IA { 
        
//
// @Override
// public void cry() { 
        
// System.out.println("老虎");
// }
//}

class Father{ 
         //类
    public Father(String name) { 
         //构造器
        super();
    }
    public void test() { 
         //方法
    }
}

基于类的演示

/* 演示匿名内部类的使用(基于接口) */
public class AnonymousInnerClass { 
        
    public static void main(String[] args) { 
        
        Outer04 outer04 = new Outer04();
        outer04.method();
    }
}

class Outer04{ 
         //外部类
    private int n1 = 10; //属性
    public void method() { 
        
        //基于接口的匿名内部类
        /* 1.需求:想使用接口IA,并创建对象 2.传统方法,写一个类,实现该接口,并创建对象 3.需求是 Tiger 类只能使用一次,后面不再使用 4.可以使用匿名内部类来简化开发 5.tiger 的编译类型是 IA 6.tiger 的运行类型是 就是 匿名内部类 名为 Outer04$1 7.jdk底层在创建匿名内部类 Outer04$1,立即马上就创建了 Outer04$1实例, 并把地址返回个 tiger 8.匿名内部类使用一次,就不能再使用 我们 */
        IA tiger =  new IA() { 
        

            @Override
            public void cry() { 
        
                System.out.println("老虎");
            }
        };
        tiger.cry();
        System.out.println("tiger的运行类型=" + tiger.getClass());
// IA tiger = new Tiger();
// tiger.cry();

        //演示基于类的匿名内部类
        //分析
        //1. father 编译类型 Father
        //2. father 运行类型 Outer04$2
        Father father = new Father("jack") { 
        
            @Override
            public void test() { 
        
                System.out.println("匿名内部类重写了test方法");
            }
        };
        System.out.println("father的运行类型=" + father.getClass());
        father.test();

    }
}

interface IA{ 
         //接口
    public void cry();
}

//class Tiger implements IA { 
        
//
// @Override
// public void cry() { 
        
// System.out.println("老虎");
// }
//}

class Father{ 
         //类
    public Father(String name) { 
         //构造器
        super();
    }
    public void test() { 
         //方法
    }
}

两种调用匿名内部类方式

public class AnonymousInnerClassDetail { 
        
    public static void main(String[] args) { 
        
        Outer05 outer05 = new Outer05();
        outer05.f1();
    }
}

class Outer05 { 
        
    private int n1 = 99;
    public void f1() { 
        
        //创建一个基于类的匿名内部类
        Person p = new Person(){ 
        
            @Override
            public void hi() { 
        
                System.out.println("匿名内部类重写了 hi方法");
            }
        };
        p.hi();//动态绑定,运行类型是 Outer05$1

        //也可以直接调用,匿名内部类本身也是返回值对象
        //class 匿名内部类 extends Person {}
        new Person(){ 
        
            @Override
            public void ok(String str) { 
        
                super.ok(str);
            }
        }.ok("jack");
    }
}

class Person { 
        //类
    public void hi() { 
        
        System.out.println("Person hi()");
    }public void ok(String str) { 
        
        System.out.println("Person ok()" + str);
    }
}

案例

package com.zzj.innerclass;

import javafx.scene.control.Cell;

public class InnerClassExercise02 { 
        
    public static void main(String[] args) { 
        
        Cellphone cellphone = new Cellphone();

        /* 1.传递的是实现了 Bell接口的匿名内部类 2.重写了 ring 3.Bell bell = new Bell() { @Override public void ring() { System.out.println("懒猪起床了!!!"); } } */

        cellphone.alarmclock(new Bell() { 
        
            @Override
            public void ring() { 
        
                System.out.println("懒猪起床了!!!");
            }
        });
        cellphone.alarmclock(new Bell() { 
        
            @Override
            public void ring() { 
        
                System.out.println("小伙伴上学了!!");
            }
        });
    }
}

interface Bell { 
         //铃声接口
    void ring();
}

class Cellphone { 
         //手机类
    public void alarmclock(Bell bell) { 
         //形参是Bell接口类型
        bell.ring();//动态绑定
    }
}

成员内部类的使用

说明: 成员内部类是定义在外部类的成员位置,并且没有static修饰。

  1. 可以直接访问内外部类的所有成员包含私有的

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

  3. 作用域 和外部类的其他成员一样,为整个类体比如前面案例,在外部类的成员方法中创建内部类对象,在调用方法。

  4. 成员内部类—访问—>外部类(比如:属性)【访问方法:直接访问】

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

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

    //外部其他类,使用成员内部类的2种方法
    //1
    //outer08.new Inner08(); 相当于把 new Inner08()当做是outer08成员
    Outer08 outer08 = new Outer08();
    Outer08.Inner08 inner08 = outer08.new Inner08();
    //2
    //在外部类中,编写一个方法,可以返回 Inner08对象
    Outer08.Inner08 inner08Instance = outer08.getInner08Instance();
    
    Public Inner08 getInner08Instance() { 
              
        retrun new Innero8();
    }
    
  7. 如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.this.成员)去访问

静态内部类的使用

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

  1. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
  2. 可以添加任意修饰符(public、protected、默认、private),因为它的地位就是一个成员
  3. 作用域:同其他的成员,为一个类体
  4. 静态内部类—访问—>外部类(比如:静态属性)【访问方式:直接访问所有静态成员】
  5. 外部类—访问—>静态内部类 访问方式:创建对象,再访问
  6. 外部其他类—访问—>静态内部类
  7. 如果外部类和静态内部类的成员重名时,静态内部类访问的时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类名.成员)去访问

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-adUUDoWP-1658839408138)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1655985071969.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-rrJYE0qK-1658839408139)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1655985737670.png)]

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qW5Q1zvX-1658839408139)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1655985681469.png)]

枚举类

  1. 枚举对应英文(enumeration , 简写 enum)
  2. 枚举十一组常量的集合。
  3. 可以这里理解:枚举属于一种特殊的类,里面只包含一组有限的特定的对象。

实现方式

  1. 自定义实现枚举
  2. 使用enum关键字实现枚举

自定义实现枚举

  1. 不许要提供setXxx方法,因为枚举数组对象值通常为只读。
  2. 对枚举对象/属性使用 final + static 共同修饰, 实现底层优化。
  3. 枚举对象名通常使用大写,常量的命名规范。
  4. 枚举对象根据需要,也可以有多个属性。
package com.zzj.enum_;

/** * @author 张正杰 * @version 1.0 */
public class Enumeration02 { 
        
    public static void main(String[] args) { 
        
        System.out.println(Season.SPRING);
    }
}

//演示自定义枚举实现
class Season { 
         //类
    private String name;
    private String desc; //描述

    public static final Season SPRING = new Season("春天","温暖");
    public static final Season WINTER = new Season("冬天","寒冷");
    public static final Season AUTUMN = new Season("秋天","凉爽");
    public static final Season SUMMER = new Season("夏天","炎热");

    //1.将构造器私有化,目的防止 直接 new
    //2.去掉setXX方法,防止属性被修改
    //3.在Season 内部,直接创建固定的对象
    //4.优化,可以加入 final 修饰符
    private Season(String name, String desc) { 
        
        this.name = name;
        this.desc = desc;
    }

    public String getName() { 
        
        return name;
    }

    public String getDesc() { 
        
        return desc;
    }

    @Override
    public String toString() { 
        
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

enum关键字实现枚举

  1. 使用关键字 enum 代替 class

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

    Season(“春天”,“温暖”) 解读 常量名(实参列表)

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

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

package com.zzj.enum_;

/** * @author 张正杰 * @version 1.0 */
public class Enumeration03 { 
        
    public static void main(String[] args) { 
        
        System.out.println(Season.SPRING);
    }
}

//演示enum关键字枚举实现
enum Season2 { 
         //类

// public static final Season SPRING = new Season("春天","温暖");
// public static final Season WINTER = new Season("冬天","寒冷");
// public static final Season AUTUMN = new Season("秋天","凉爽");
// public static final Season SUMMER = new Season("夏天","炎热");
// 如果使用了enum 来实现枚举类
    SPRING("春天","温暖"),
    WINTER("冬天","寒冷"),
    AUTUMN("秋天","凉爽"),
    SUMMER("夏天","炎热");
    private String name;
    private String desc; //描述

    private Season2(String name, String desc) { 
        
        this.name = name;
        this.desc = desc;
    }

    public String getName() { 
        
        return name;
    }

    public String getDesc() { 
        
        return desc;
    }

    @Override
    public String toString() { 
        
        return "Season{" +
                "name='" + name + '\'' +
                ", desc='" + desc + '\'' +
                '}';
    }
}

enum关键字实现枚举注意事项

  1. 当我们使用enum 关键字开发一个枚举类时, 默认会继承Enum类【如何证明】

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

    Season(“春天”,“温暖”) 这里必须知道, 他调用的是哪个构造器。

    如果我们使用的是无参构造器,创建常量对象,则可以省略()。

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

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

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

enum 常用方法

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-AW7yOTqA-1658839408140)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1656224164592.png)]

package com.zzj.enum_;

/** * @author 张正杰 * @version 1.0 *演示Enum 类的各种方法的使用 */
public class EnumMethod { 
        
    public static void main(String[] args) { 
        
        //使用Season2 枚举类, 来演示各种方法
        Season2 autumn = Season2.AUTUMN;
        //输出枚举对象的名字
        System.out.println(autumn.name());
        //ordinal() 输出的是该枚举对象的次序/编号,从0开始编号
        //AUTUMN 枚举对象是第三个 , 因此输出 2
        System.out.println(autumn.ordinal());
        //从反编译可以看出 values 方法,返回 Season2[]
        //含有定义的所有枚举对象
        Season2[] values = Season2.values();
        for (Season2 season : values) { 
         //增强for循环
            System.out.println(season);
        }
        //valueof:将字符串转换成枚举对象,要求字符串必须VT为已有的常量名,否则报异常。
        //执行流程
        //1.根据你输入的“AUTUMN” 到 Season2的枚举对象去查找
        //2.如果找到了,就返回,如果没有找到,就报错
        Season2 autumn1 = Season2.valueOf("AUTUMN");
        System.out.println("autumn1=" + autumn1);
        //compareTo:比较两个枚举常量,比较的就是编号
        System.out.println(Season2.AUTUMN.compareTo(Season2.SUMMER));
     }
}

enum实现接口

  1. 使用 enum关键字 后, 就不能在继承其他类了,因为 enum 会隐式继承Enum,而java是单继承机制。

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

    enum 类名 implements 接口1,接口2{}

注解

  1. 注解(Annotation)也被称为元数据(Metadata),用于修饰解释 包、类、方法、属性、构造器、局部变量等信息。
  2. 和注释不一样,注解不影响程序逻辑,但注解可以被编译或者运行,相当于嵌入在代码中的补充信息。
  3. 在JavaSE中,注解的使用目的比较简单,例如标记过时的功能,忽略警告等,在javaEE中注解占据了重要的角色,例如用来配置应用程序的任何切面,代替javaEE 旧版中所遗留的繁冗代码和XML配置等。

Annotation介绍

使用Annotation时要在其前面增加@符号,并把该Annotation当成一个修饰符使用。用于修饰它支持的程序元素

三个基本的Annotation:

  1. @Override:限定某个方法,是重写父类方法,该注解只能用于方法
  2. @Deprecated:用于表示某个程序元素(类,方法等)已过时
  3. @SuppressWarnings:抑制编译器警告

Override使用说明

  1. @Override便是指定重写父类的方法(从编译层面验证),如果父类没有Fly方法,则会报错。
  2. 如果不懈@Override注解,而父类仍有 Public void fly() {} ,仍然构成重写
  3. @Override 只能修饰方法,不能修饰其他类,包、属性等等
  4. 查看@Override注解原码为 @Target(ElementType.METHOD),说明只能修饰方法
  5. @Target是修饰注解的注解,成为元注解

Deprecated的说明

  1. 用于表示某个程序元素(类,方法等)已过时
  2. 可以修饰方法,类,字段,包,参数 等等
  3. @Target(value = {CONSTRUCTOR,FIELD,LOCAL_VARIABLE,METHOD,PACKAGE,PARAMETER,TYPE})
  4. @Deprecated 的作用可以做到新旧版版本的兼容和过渡

SuppressWarnings各种值的说明

  1. unchecked是忽略没有检查的警告
  2. rawtypes 是忽略没有指定泛型的警告(传参时没有指定泛型的警告错误)
  3. unused是忽略没有使用某个变量的警告错误
  4. @SuppressWarnings 可以修饰的程序元素为,查看@Target
  5. 生成@SuppressWarnings时,不用背,直接点击左侧的黄色提示,就可以选择(注意可以指定生成的位置)

JDK 的元 Annotation(元注解)

元注解基本介绍

JDK 的 元 Annotation 用于修饰其他 Annotation

元注解:本身作用不大。

元注解的种类

  1. Retention // 指定注解的作用范围 , 三种 SOURCE,CLASS,RUNTIME
  2. Target // 指定注解可以在那些地方使用
  3. Documented //指定该注解是否会在javadoc体现
  4. Inherited //子类后继承父类注解

练习

[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-k6kO8FG8-1658839408140)(C:\Users\lenovo\AppData\Roaming\Typora\typora-user-images\1656310243568.png)]

package com.zzj.annotaition;

/** * @author 张正杰 * @version 1.0 */
public class Homework06 { 
        
    public static void main(String[] args) { 
        
        Person tang = new Person(
        标签: 继电器底座dtf08a

锐单商城拥有海量元器件数据手册IC替代型号,打造 电子元器件IC百科大全!

锐单商城 - 一站式电子元器件采购平台