Loading... > 【注意】文章是博主在整体学习完JavaSE内容后进行整理的,所以文中的一些内容在后续的文章中有更详细的讲解,可以点击超链接查看,也可以先跳过该部分内容,看到后面的时候再返回来看。 > 学习编程就是一个不断重复、不断思考的过程!加油! # 什么是类 类是一组相关的属性和行为的集合。可以看成是一类事物的模板,使用事物的属性特征和行为特征来描述该类事物。 # 什么是对象 对象是一类事物的具体体现。对象是类的一个实例,具备该类事物的属性和行为。 # 类的定义 ```java has-numbering public class 类名{ 成员变量; // 属性 成员方法; // 行为 } 1234 ``` 【注意】 1. 成员变量定义在类中,方法外; 2. 成员方法前不要写static关键字。 3. 通常情况下一个类并不能直接使用,需要根据类创建一个对象才能使用。 ## 成员变量和局部变量的区别 1. 定义位置不同 * 成员变量:类中,方法外 * 局部变量:方法内部 2. 作用范围不同 * 成员变量:类中 * 局部变量:方法中 3. 初始化值不同 * 成员变量:有默认初始值(和数组的规则一致) * 局部变量:没有默认初始值,必须先定义、赋值,才能使用 4. 内存位置不同 * 成员变量:堆内存 * 局部变量:栈内存 5. 生命周期不同 * 成员变量:随着对象的创建而存在,随着对象的消失而消失 * 局部变量:随着方法进栈而产生,随着方法出栈而消失 ## 构造方法 [封装的优化](https://blog.fivk.cn/archives/818.html)中进行详细阐述。 ## 抽象类 包含[抽象方法](https://blog.fivk.cn/archives/810.html)的类。使用`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 * 局部内部类:不能使用权限修饰符,只能在本方法中使用。 #### 成员内部类 定义在类中方法外的类。 ```java has-numbering 修饰符 class 外部类名称 { 修饰符 class 内部类名称 { // } } ``` * 访问特点 * 内部类可以直接访问外部类的成员,包括私有成员; * 外部类要访问内部类的成员,则必须创建内部类对象; * 间接访问:在外部类的方法中访问内部类,然后调用外部类的方法即可访问内部类的成员; * 直接访问:直接创建内部类对象访问。 * 创建内部类对象的格式:使用外部类对象创建内部类对象 `外部类名称.内部类名称 对象名 = new 外部类名称().new 内部类名称();` 【注意】 内部类与外部类成员变量同名: `外部类名称.this.外部类成员变量名` * 示例 ```java has-numbering 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; } } ``` 测试类 ```java has-numbering 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(); } } ``` #### 局部内部类 一个类定义在一个方法内部。 ```java has-numbering 修饰符 class 外部类名称 { 修饰符 返回值类型 方法名(参数列表) { class 局部内部类名称 { // } } } ``` 【注意】 局部内部类如果想要访问所在方法的局部变量,那么这个局部变量必须是一个有效final的。 * 原因 1. new出来的对象在对内存中,等到GC回收才消失; 2. 局部变量在栈内存,方法执行结束,局部变量则消失。 【备注】 jdk8开始,只要局部变量事实不变,那么final关键字可以省略。 #### 匿名内部类 如果接口的实现类(或者父类的子类)只需要使用一次,那么可以省略该类的定义,使用匿名内部类。 匿名内部类的本质是:一个 带具体实现的 父类或者接口的 匿名的 子类对象。 * 前提:匿名内部类必须继承一个父类或者实现一个接口 * 格式 ```java has-numbering 父类或者接口名称 对象名 = new 父类或者接口名称() { // 以下是匿名内部类的内容 // 重写父类或者接口的所有抽象方法 } ``` * 匿名内部类和匿名对象的区别 1. 匿名内部类创建对象时,只能使用一次; 2. 匿名内部类省略了子类或者实现类的名称; 3. 匿名对象调用方法时,只能使用一次; 4. 匿名对象省略了对象名。 * 使用方式 * 创建对象使用 * 方法的形式参数是接口或者抽象类时,可以使用匿名内部类作为参数传递 * 示例 ```java has-numbering package com.junlong.plan; /** * @Author: junlong.zhou * @Date: 2021/6/25 18:28 * @Version 1.0 */ public interface Plan { void fly(); } ``` ```java has-numbering 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包下的类可以不用导包。 2. 创建对象 `类名 对象名 = new 类名();` 3. 使用 * 成员变量:`对象名.成员变量;` * 成员方法:`对象名.成员方法();` 【注意】 * 如果成员变量没有赋值,那么会有一个默认值; | 整数 | 浮点数 | 字符 | 布尔 | 引用 | | ------ | -------- | ------------ | ------- | ------ | | 0 | 0.0 | ‘\U0000’ | false | null | * 使用对象作为方法的参数或返回值,传递的是对象在内存中的地址值。 ## 对象的内存原理 new出来的对象在堆内存中存储,其成员变量和成员方法自然也在堆内存中。当调用对象的成员方法时,使用对象的方法标记去方法区的class找方法信息执行。 ![对象内存原理](https://blog.fivk.cn/usr/uploads/2021/11/3160816712.png) ## 匿名对象 创建对象时,只有创建对象的语句,没有把对象的地址赋值给某个变量。是创建对象的简化写法,应用场景有限。 【注意】 1. 创建匿名对象直接调用其方法,没有变量名; 2. 一个匿名对象只能使用一次; 3. 匿名对象可以作为方法的参数或返回值。 ## 引用类型用法总结 ### 类作为成员变量 类作为成员变量时,对它进行赋值的操作,实际上是赋给它该类的一个对象。 ### 接口作为成员变量 接口作为成员变量时,对它进行赋值的操作,实际上是赋给它该接口的一个子类对象。 ### 接口作为方法的参数或返回值 接口作为方法的参数时,传递它的子类对象; 接口作为方法的返回值时,返回它的子类对象。 > 感谢小伙伴们的关注! > 你的点赞、评论、关注、收藏是对博主的最大鼓励! > 持续更新JavaSE学习笔记!欢迎订阅专栏! 最后修改:2021 年 11 月 11 日 © 允许规范转载 打赏 赞赏作者 支付宝微信 赞 如果觉得我的文章对你有用,请随意赞赏