JavaSE知识重构

JavaSE知识重构

我亦无他,唯手熟尔。

参考:
B站【零基础 快速学Java】韩顺平 零基础30天学会Java


final关键字

final可以修饰类、属性、方法和局部变量

需要使用final的需求:

  1. 类不可以被继承
  2. 父类的某个方法不可以被子类覆盖/继承(override)
  3. 类的某个属性值不可以被修改
  4. 某个局部变量不可以被修改

final注意细节

  1. final修饰的属性叫做常量,XXX_XXX_XXX来命名
  2. final修饰的属性在定义时,必须赋初值,并且之后不能修改。
    赋值可以在如下位置:
    • 定义时
    • 在构造器中
    • 在代码块中
  3. 如果final修饰的属性是静态的,则初始化的位置只能是:
    • 定义时
    • 在静态代码块,不能在构造器中赋值
  4. final类不能继承,但可以实例化对象
  5. 如果类不是final类,但含有final方法,则该方法不能重写,但可以被继承。
  6. 如果一个类已经是final类了,没必要再将方法修饰成final方法
  7. final不能修饰构造方法(即构造器)
  8. final、static往往搭配使用,效率高,不会导致类加载(底层编译器做了优化处理)
  9. 包装类(Integer, Double, Float, Boolean等都是final),String类也是final类。

抽象类

exercise:
1、abstract final class A{}能编译通过嘛?错误,final不能继承
2、abstract public static void test2();能编译通过吗?错误,static关键字和方法重写无关。
3、abstract private void test3();错误,私有的方法不能重写。
模板设计模式:

接口

内部类

类的五大成员:
属性、方法、构造器、代码块、内部类

什么是内部类

一个类的内部又完整的嵌套了另一个类结构。被嵌套的类称为内部类(inner class),嵌套其他类的类称为外部类(outer class)。
内部类最大的特点就是可以直接访问私有属性,并且可以体现类与类之间的包含关系。
定义类在局部位置(方法中/代码块):(1)局部内部类(2)匿名内部类
定义在成员位置:(1)成员内部类(2)静态内部类
在这里插入图片描述

内部类的特点

  1. 内部类仍然是一个独立的类,在编译之后内部类会被编译成独立的.class文件,但是前面冠以外部类的类名和$符号。
  2. 内部类不能用普通的方式访问。内部类是外部类的一个成员,因此内部类可以自由地访问外部类的成员变量,无论是否为 private 的。
  3. 内部类声明成静态的,就不能随便访问外部类的成员变量,仍然是只能访问外部类的静态成员变量。

局部内部类的使用

局部内部类是定义在外部类的局部位置,比如方法中,并且有类名。

  1. 可以直接访问外部类的所有成员,包括私有的。
  2. 不能添加访问修饰符,因为它的地位就是一个局部变量。局部变量是不能使用修饰符的。但是可以使用final修饰,因为局部变量也可以使用final
  3. 作用域:仅仅在定义它的方法或代码块中。
  4. 局部内部类–访问---->外部类成员 【访问方式:直接访问】
  5. 外部类–>访问—>局部内部类成员 【访问方式:创建对象,再访问(注意:必须在作用域内)】
    注意:
    1 局部内部类定义在方法中/代码块中
    2 作用域再方法体或者代码块中
    3 本质仍然是一个类
  6. 外部其他类–不能访问---->局部内部类(因为 局部内部类地位是一个局部变量)
  7. 如果外部类和局部内部类的成员重名时,默认遵循就近原则,如果想访问外部类的成员,则可以使用(外部类.this.成员)去访问
public class LocalInnerClass {
    public static void main(String[] args) {
        Outer01 outer01 = new Outer01();
        outer01.outer_02();
        System.out.println("outer01的hashcode = " + outer01);
    }
}

class Outer01{  //外部类
    private int n1 = 100;
    private void outer_f1(){
        System.out.println("外部类实例方法");
    }
    public void outer_02(){  //方法
        // 局部内部类是定义在外部类的局部位置上,通常在方法
        // 不能添加访问修饰符,但是可以使用final修饰
        // 作用域:仅仅在定义它的方法或代码块中
        class Inner01{  //局部内部类(本质仍然是一个类)
            private int n1 = 800;
            public void inner_f1(){
                // 局部内部类可以直接访问外部类的成员
                // 如果外部类和内部类的成员重名,默认遵循就近原则
                // 如果想访问外部类的成员 使用 外部类类名.this.成员 去访问
                // Outer01.this 本质就是外部类的对象
                System.out.println("n1 = " + n1);
                System.out.println("外部类的n1 = " + Outer01.this.n1);
                System.out.println("Outer01.this hashcode = " + Outer01.this);
            }
        }

        Inner01 inner01 = new Inner01();
        inner01.inner_f1();
    }
}

n1 = 800
外部类的n1 = 100
Outer01.this hashcode = chapter10.innerclass.Outer01@1b6d3586
outer01的hashcode = chapter10.innerclass.Outer01@1b6d3586

匿名内部类的使用

1、本质是类
2、内部类
3、该类没有名字
4、同时还是一个对象
说明:匿名内部类是定义在外部类的局部位置,比如方法中,并且没有类名
匿名内部类的基本语法

new 类或接口(参数列表){
	类体
}
public class AnonymousInnerClass {
    public static void main(String[] args) {
        Outer02 outer02 = new Outer02();
        outer02.method();
    }
}

class Outer02{
    //基于接口的匿名内部类
    //1.需求: 想使用IA接口,并创建对象
    //2.传统方式,是写一个类,实现该接口,并创建对象
    //3.老韩需求是 Tiger/Dog 类只是使用一次,后面再不使用
    //4. 可以使用匿名内部类来简化开发
    //5. tiger的编译类型 ? IA
    //6. tiger的运行类型 ? 就是匿名内部类  Outer04$1
        /*
            底层 会分配 类名 Outer04$1
            class Outer04$1 implements IA {
                @Override
                public void cry() {
                    System.out.println("老虎叫唤...");
                }
            }
         */
    //7. jdk底层在创建匿名内部类 Outer04$1,马上就创建了 Outer04$1实例,并且把地址
    //   返回给 tiger
    //8. 匿名内部类使用一次,就不能再使用
    public void method(){
        IA tiger = new IA(){

            @Override
            public void fun() {
                System.out.println("老虎叫唤...");
            }
        };
        System.out.println("tiger的运行类型 = " + tiger.getClass());
    }

}

interface IA{
    void fun();
}

tiger的运行类型 = class chapter10.innerclass.Outer02$1

匿名内部类可以访问外部类的所有成员,包含私有的。
不能添加访问修饰符,因为他的地位就是一个局部变量
作用域:仅仅在定义它的方法或者代码块中
外部其他类不能访问匿名内部类(因为匿名内部类地位是一个局部变量)
如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类名.this.成员)去访问。

//基于类的匿名内部类
 //分析
 //1. father编译类型 Father
 //2. father运行类型 Outer04$2
 //3. 底层会创建匿名内部类
 /*
     class Outer04$2 extends Father{
         @Override
         public void test() {
             System.out.println("匿名内部类重写了test方法");
         }
     }
  */
 //4. 同时也直接返回了 匿名内部类 Outer04$2的对象
 //5. 注意("jack") 参数列表会传递给 构造器
 Father father = new Father("tom"){
     @Override
     public void test() {
         System.out.println("匿名内部类重写test方法");
     }
 };
 System.out.println("father 对象的运行类型= " + father.getClass());
//        father.test();

 //基于抽象类的匿名内部类
 Animal animal = new Animal() {

     @Override
     void eat() {
         System.out.println("小狗吃骨头...");
     }
 };
 System.out.println("animal对象的运行类型=" + animal.getClass());
 animal.eat();

接收到的name=tom
father 对象的运行类型= class chapter10.innerclass.Outer02$2
animal对象的运行类型=class chapter10.innerclass.Outer02$3
小狗吃骨头…

public class AnonymousInnerClassDetail {
    public static void main(String[] args) {
        Outer03 outer03 = new Outer03();
        outer03.f1();
        //外部其他类---不能访问----->匿名内部类
        System.out.println("main outer03 hashcode=" + outer03);
    }
}

class Outer03{
    private int n1 = 99;
    public void f1() {
        //创建一个基于类的匿名内部类
        //不能添加访问修饰符,因为它的地位就是一个局部变量
        //作用域 : 仅仅在定义它的方法或代码块中
        Person p = new Person(){
            private int n1 = 88;
            @Override
            public void hi() {
                //可以直接访问外部类的所有成员,包含私有的
                //如果外部类和匿名内部类的成员重名时,匿名内部类访问的话,
                //默认遵循就近原则,如果想访问外部类的成员,则可以使用 (外部类名.this.成员)去访问
                System.out.println("匿名内部类重写了 hi方法 n1=" + n1 +
                        " 外部内的n1=" + Outer03.this.n1 );
                //Outer05.this 就是调用 f1的 对象
                System.out.println("Outer03.this hashcode=" + Outer03.this);
            }
        };
        p.hi();//动态绑定, 运行类型是 Outer03$1

        //也可以直接调用, 匿名内部类本身也是返回对象
        // class 匿名内部类 extends Person {}
        new Person(){
            @Override
            public void hi() {
                System.out.println("匿名内部类重写了 hi方法,哈哈...");
            }
            @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);
    }
}

匿名内部类重写了 hi方法 n1=88 外部内的n1=99
Outer03.this hashcode=chapter10.innerclass.Outer03@1b6d3586
Person ok() jack
main outer03 hashcode=chapter10.innerclass.Outer03@1b6d3586

public class InnerClassExercise02 {
    public static void main(String[] args) {
        /*
        1.有一个铃声接口Bell,里面有个ring方法。(右图)
        2.有一个手机类Cellphone,具有闹钟功能alarmClock,参数是Bell类型(右图)
        3.测试手机类的闹钟功能,通过匿名内部类(对象)作为参数,打印:懒猪起床了
        4.再传入另一个匿名内部类(对象),打印:小伙伴上课了
         */
        CellPhone cellPhone = new CellPhone();
        //老韩解读
        //1. 传递的是实现了 Bell接口的匿名内部类 InnerClassExercise02$1
        //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接口类型
        System.out.println(bell.getClass());
        bell.ring();//动态绑定
    }
}

成员内部类使用

成员内部类是定义在外部类的成员位置,并且没有static修饰。
1、可以直接访问外部类的所有成员,包括私有的。
2、可以添加任意访问修饰符(public、protected、默认、private),因为它的地位就是一个成员。
3、作用域:和外部类的其他成员一样,为整个类。
4、成员内部类–访问---->外部类成员(属性)【访问方式:直接访问】
5、外部类–访问---->成员内部类【访问方式:创建对象,再访问】
6、外部其他类–访问---->成员内部类
7、如果外部类和内部类的成员重名时,内部类访问的话,默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类.this.成员)去访问

静态内部类的使用

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

public class StaticInnerClass01 {
    public static void main(String[] args) {
        Outer05 outer05 = new Outer05();
        outer05.m1();

        // 外部其它类 使用静态内部类
        // 方式一
        Outer05.Inner05 inner05 = new Outer05.Inner05();
        inner05.say();

        // 方式2
        // 编写一个方法,可以返回静态内部类的对象实例
        Outer05.Inner05 inner051 = outer05.getInner05();
        inner05.say();
        Outer05.Inner05 inner05_ = Outer05.getInner05_();
        inner05.say();
    }
}


class Outer05{
    private int n1 = 10;
    private static String name = "张三";
    private static void cry(){};

    //Inner05就是静态内部类
    //1. 放在外部类的成员位置
    //2. 使用static 修饰
    //3. 可以直接访问外部类的所有静态成员,包含私有的,但不能直接访问非静态成员
    //4. 可以添加任意访问修饰符(public、protected 、默认、private),因为它的地位就是一个成员
    //5. 作用域 :同其他的成员,为整个类体
    static class Inner05{
        private static String name = "我亦无他,唯手熟尔。";
        // 如果外部类和静态内部类的成员重名时,静态内部类访问的时候
        // 默认遵循就近原则,如果访问外部类的成员,则可以使用(外部类名.成员)
        public void say(){
            System.out.println(name + " 外部类name = " + Outer05.name);
            // 静态内部类直接使用外部类的静态方法
            cry();
        }
    }

    //外部类---访问------>静态内部类 访问方式:创建对象,再访问
    public void m1(){
        Inner05 inner05 = new Inner05();
        inner05.say();
    }

    public Inner05 getInner05(){
        return new Inner05();
    }

    public static Inner05 getInner05_(){
        return new Inner05();
    }
}

枚举和注解

枚举

1、使用enum关键字实现枚举类,默认继承Enum类,而且是一个final类
2、如果使用无参构造器创建枚举对象,则实参列表和小括号可以省略
3、当有多个枚举对象时,使用逗号间隔,最后有一个分号结尾。
4、枚举对象必须放在枚举类的行首

public class Enumeration03 {
    public static void main(String[] args) {
        System.out.println(Season2.AUTUMN);
        System.out.println(Season2.SUMMER);
    }
}
//演示使用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 来实现枚举类
    //1. 使用关键字 enum 替代 class
    //2. public static final Season SPRING = new Season("春天", "温暖") 直接使用
    //   SPRING("春天", "温暖") 解读 常量名(实参列表)
    //3. 如果有多个常量(对象), 使用 ,号间隔即可
    //4. 如果使用enum 来实现枚举,要求将定义常量对象,写在前面
    //5. 如果我们使用的是无参构造器,创建常量对象,则可以省略 ()
    SPRING("春天", "温暖"), WINTER("冬天", "寒冷"), AUTUMN("秋天", "凉爽"),
    SUMMER("夏天", "炎热")/*, What()*/;

    private String name;
    private String desc;//描述

    private Season2() {//无参构造器

    }

    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. toString:Enum 类已经重写过了,返回的是当前对象名,子类可以重写该方法,用于返回对象的属性信息
  2. name:返回当前对象名(常量名),子类中不能重写
  3. ordinal:返回当前对象的位置号,默认从0 开始
  4. values:返回当前枚举类中所有的常量
  5. valueOf:将字符串转换成枚举对象,要求字符串必须为已有的常量名,否则报异常!
  6. compareTo:比较两个枚举常量,比较的就是编号!
  7. 使用enum 关键字后,就不能再继承其它类了,因为enum 会隐式继承Enum,而Java 是单继承机制。
  8. 枚举类和普通类一样,可以实现接口

注解

异常

常用类

String类

在这里插入图片描述
在这里插入图片描述

hsp and hava

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

树下一朵云

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值