【注意】文章是博主在整体学习完JavaSE内容后进行整理的,所以文中的一些内容在后续的文章中有更详细的讲解,可以点击超链接查看,也可以先跳过该部分内容,看到后面的时候再返回来看。
学习编程就是一个不断重复、不断思考的过程!加油!

什么是类

类是一组相关的属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。

什么是对象

对象是一类事物的具体体现。对象是类的一个实例,具备该类事物的属性和行为。

类的定义

public class 类名{
    成员变量; // 属性
    成员方法; // 行为
}
1234

【注意】

  1. 成员变量定义在类中,方法外;
  2. 成员方法前不要写static关键字。
  3. 通常情况下一个类并不能直接使用,需要根据类创建一个对象才能使用。

成员变量和局部变量的区别

  1. 定义位置不同

    • 成员变量:类中,方法外
    • 局部变量:方法内部
  2. 作用范围不同

    • 成员变量:类中
    • 局部变量:方法中
  3. 初始化值不同

    • 成员变量:有默认初始值(和数组的规则一致)
    • 局部变量:没有默认初始值,必须先定义、赋值,才能使用
  4. 内存位置不同

    • 成员变量:堆内存
    • 局部变量:栈内存
  5. 生命周期不同

    • 成员变量:随着对象的创建而存在,随着对象的消失而消失
    • 局部变量:随着方法进栈而产生,随着方法出栈而消失

构造方法

封装的优化中进行详细阐述。

抽象类

包含抽象方法的类。使用abstract关键字修饰。
abstract class 类名 {}
【注意】

  1. 不能直接创建(new)抽象类对象;
  2. 必须用一个子类继承抽象父类;
  3. 子类必须重写(实现)父类的所有抽象方法,除非该子类也是一个抽象类;
  4. 使用具体的子类创建对象,调用方法;
  5. 抽象类可以有构造方法,用于子类创建对象时,初始化父类成员;
  6. 抽象类中不一定有抽象方法(适配器模式),有抽象方法的类一定是抽象类。

内部类

一个类A定义在另一个类B内部,内部的类A就称为内部类,外部的类B则称为外部类。
内部类分为:成员内部类和局部内部类,局部内部类包括匿名内部类。
内部类是一个独立的类,会被编译成独立的.class文件,但是文件名为:外部类名$内部类名.class。如:Human$Heart.class

  • 内部类权限修饰符使用规则

    • 外部类:public / default
    • 成员内部类:public / protected / default / private
    • 局部内部类:不能使用权限修饰符,只能在本方法中使用。

成员内部类

定义在类中方法外的类。

修饰符 class 外部类名称 {
    修饰符 class 内部类名称 {
        //
    }
}
  • 访问特点

    • 内部类可以直接访问外部类的成员,包括私有成员;
    • 外部类要访问内部类的成员,则必须创建内部类对象;
    • 间接访问:在外部类的方法中访问内部类,然后调用外部类的方法即可访问内部类的成员;
    • 直接访问:直接创建内部类对象访问。
  • 创建内部类对象的格式:使用外部类对象创建内部类对象

外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();
【注意】
内部类与外部类成员变量同名:
外部类名称.this.外部类成员变量名

  • 示例
package com.junlong.man;

/**
 * @Author: junlong.zhou
 * @Date: 2021/6/25 17:53
 * @Version 1.0
 */
public class Human {
    private boolean live = false; // 存活状态

    // 心脏成员内部类
    class Heart {
        private boolean live = false; // 内部类成员变量
        // 心脏跳动
        public void jump() {
            // 内部类成员变量和外部类成员变量同名,访问外部类成员变量格式:外部类名.this.外部类成员变量名
            if (Human.this.live) {
                System.out.println("心脏在跳动...蹦蹦蹦...");
            }else {
                System.out.println("心脏停止跳动!");
            }
        }
    }

    public boolean isLive() {
        return live;
    }

    public void setLive(boolean live) {
        if (live) {
            System.out.println("人工呼吸,救活她♥♥♥");
        }else {
            System.out.println("kill 他 qvq");
        }
        this.live = live;
    }
}

测试类

package com.junlong.man;

/**
 * @Author: junlong.zhou
 * @Date: 2021/6/25 17:57
 * @Version 1.0
 */
public class test {
    public static void main(String[] args) {
        // 创建外部类对象
        Human human = new Human();
        // 创建内部类对象
        Human.Heart heart = human.new Heart();
        // 调用内部类方法
        heart.jump();
        // 调用外部类方法:活着就kill他,dead就救活她
        human.setLive(!human.isLive());
        // 调用内部类方法
        heart.jump();
    }
}

局部内部类

一个类定义在一个方法内部。

修饰符 class 外部类名称 {
    修饰符 返回值类型 方法名(参数列表) {
        class 局部内部类名称 {
            //
        }
    }
}

【注意】
局部内部类如果想要访问所在方法的局部变量,那么这个局部变量必须是一个有效final的。

  • 原因

    1. new出来的对象在对内存中,等到GC回收才消失;
    2. 局部变量在栈内存,方法执行结束,局部变量则消失。

【备注】
jdk8开始,只要局部变量事实不变,那么final关键字可以省略。

匿名内部类

如果接口的实现类(或者父类的子类)只需要使用一次,那么可以省略该类的定义,使用匿名内部类。
匿名内部类的本质是:一个 带具体实现的 父类或者接口的 匿名的 子类对象。

  • 前提:匿名内部类必须继承一个父类或者实现一个接口
  • 格式
父类或者接口名称 对象名 = new 父类或者接口名称() {
    // 以下是匿名内部类的内容
    // 重写父类或者接口的所有抽象方法
}
  • 匿名内部类和匿名对象的区别

    1. 匿名内部类创建对象时,只能使用一次;
    2. 匿名内部类省略了子类或者实现类的名称;
    3. 匿名对象调用方法时,只能使用一次;
    4. 匿名对象省略了对象名。
  • 使用方式

    • 创建对象使用
    • 方法的形式参数是接口或者抽象类时,可以使用匿名内部类作为参数传递
  • 示例
package com.junlong.plan;

/**
 * @Author: junlong.zhou
 * @Date: 2021/6/25 18:28
 * @Version 1.0
 */
public interface Plan {
    void fly();
}
package com.junlong.plan;

/**
 * @Author: junlong.zhou
 * @Date: 2021/6/25 18:29
 * @Version 1.0
 */
public class AirBus {
    public static void main(String[] args) {
        // 直接使用匿名内部类创建对象使用
        Plan plan = new Plan() {
            @Override
            public void fly() {
                System.out.println("起飞...");
            }
        };
        plan.fly();

        System.out.println("==================");

        // 使用匿名内部类作为参数
        showFly(new Plan() {
            @Override
            public void fly() {
                System.out.println("我也起飞了.......");
            }
        });
    }

    public static void showFly(Plan plan) {
        plan.fly();
    }
}

对象(引用类型)的使用

使用步骤

  1. 导包

import 类的全限定名称; // 同一个包下可以不用导包;Java.lang包下的类可以不用导包。

  1. 创建对象

类名 对象名 = new 类名();

  1. 使用

    • 成员变量:对象名.成员变量;
    • 成员方法:对象名.成员方法();

【注意】

  • 如果成员变量没有赋值,那么会有一个默认值;
整数浮点数字符布尔引用
00.0‘\U0000’falsenull
  • 使用对象作为方法的参数或返回值,传递的是对象在内存中的地址值。

对象的内存原理

new出来的对象在堆内存中存储,其成员变量和成员方法自然也在堆内存中。当调用对象的成员方法时,使用对象的方法标记去方法区的class找方法信息执行。

对象内存原理

匿名对象

创建对象时,只有创建对象的语句,没有把对象的地址赋值给某个变量。是创建对象的简化写法,应用场景有限。

【注意】

  1. 创建匿名对象直接调用其方法,没有变量名;
  2. 一个匿名对象只能使用一次;
  3. 匿名对象可以作为方法的参数或返回值。

引用类型用法总结

类作为成员变量

类作为成员变量时,对它进行赋值的操作,实际上是赋给它该类的一个对象。

接口作为成员变量

接口作为成员变量时,对它进行赋值的操作,实际上是赋给它该接口的一个子类对象。

接口作为方法的参数或返回值

接口作为方法的参数时,传递它的子类对象;
接口作为方法的返回值时,返回它的子类对象。

感谢小伙伴们的关注!
你的点赞、评论、关注、收藏是对博主的最大鼓励!
持续更新JavaSE学习笔记!欢迎订阅专栏!
最后修改:2021 年 11 月 11 日
如果觉得我的文章对你有用,请随意赞赏