【04】面向对象 内部类 访问修饰符 final
📔 千寻简笔记介绍
千寻简笔记已开源,Gitee与GitHub搜索chihiro-notes
,包含笔记源文件.md
,以及PDF版本方便阅读,且是用了精美主题,阅读体验更佳,如果文章对你有帮助请帮我点一个Star
~
更新:支持在线阅读文章,根据发布日期分类。
文章目录
简介
本文关键词
static
、static的介绍
、final
、包
、为什么要使用包呢?
、包的导入(Importing Packages)
、全限定类型(Fully Qualified Type)
、权限修饰符
、内部类
、静态代码块
1 static
1.1 static
的介绍
静态(static)是一个关键字,用于修饰类的成员变量、成员方法和代码块。下面分别介绍了静态成员变量、静态成员方法和静态代码块。
- 静态成员变量:
- 静态成员变量是被所有该类的实例共享的变量。
- 静态成员变量在类加载时被初始化,并且只会被初始化一次。
- 静态成员变量可以通过类名直接访问,也可以通过对象引用访问。
- 静态成员方法:
- 静态成员方法属于类本身,而不是属于类的实例。
- 静态成员方法可以直接使用类名调用,无需创建类的实例。
- 静态成员方法不能访问非静态成员变量和非静态成员方法,只能访问静态成员变量和静态成员方法。
- 静态代码块:
- 静态代码块是在类加载时执行的代码块,优先于实例对象的创建。
- 静态代码块用于初始化静态成员变量或执行一些只需在类加载时执行一次的操作。
- 静态代码块在类加载时仅执行一次。
静态成员变量和静态成员方法主要用于以下情况:
- 当数据需要在多个实例之间共享时,可以使用静态成员变量来存储这些数据。
- 当方法不依赖于对象的状态或实例特定数据时,可以将其定义为静态成员方法。
- 当需要在类加载时执行某些初始化操作时,可以使用静态代码块。
需要注意的是,静态成员变量和静态成员方法属于类本身,而不是属于类的实例。因此,在使用静态成员时,应该遵循类名.静态成员
的方式进行访问,而不是通过实例对象进行访问。例如:ClassName.staticVariable
、ClassName.staticMethod()
。
什么时候的成员变量需要static修饰?
- 如果这个成员不属于某一个对象,而是属于所有对象共有的,那么需要加上static修饰。
2 final
final
是Java中的一个关键字,用于修饰类、成员变量和方法,具有不同的作用。
- final修饰类:
- 当一个类被修饰为final时,该类不能被继承,即不能有子类。
- 这样做的目的可能是为了防止类在被继承后被修改或破坏原有的设计。
- final修饰成员变量:
- 被final修饰的成员变量是常量,即其值在初始化之后不能再被修改。
- final成员变量必须在定义时或构造方法中赋初值,且只能赋值一次。
- 常量一般使用大写字母命名,多个单词之间使用下划线分隔。
- final修饰成员方法:
- 被final修饰的成员方法是最终方法,即子类不能重写该方法。
- 这样做可以确保该方法的实现不会被子类改变。
- final修饰局部变量:
- 被final修饰的局部变量表示一个只能赋值一次的常量。
- final局部变量必须在声明时或代码块中赋值,并且只能赋值一次。一旦赋值后,其值就不可再修改。
- 常用于匿名内部类中,以确保在内部类中可以访问到该变量。
总之,使用final关键字可以保护类、变量和方法的完整性和稳定性,限制其被修改或继承。
3 包
包(package)是Java中用于管理文件和组织代码的机制。它的本质就是文件夹,在文件系统中以文件夹的形式存在。
3.1 为什么要使用包呢?
- 分类管理文件:包可以将相关的类和资源文件组织在一起,形成逻辑上的模块化结构。这样可以方便开发者对文件进行分类和管理,提高代码的可读性和维护性。
- 命名空间隔离:包名具有全局唯一性,不同包下的类可以拥有相同的类名,但在不同的包中是可以区分的。这避免了类名冲突的问题,使得代码更加清晰和易于理解。
包的声明使用package
关键字,格式为:
package 包名;
包的声明主要指明了某个类所在的包路径,告诉编译器该类位于哪个包下。包的声明应与类的实际位置保持一致,即包名的层级结构应与文件目录结构相对应。
使用包的好处是能够将代码按照功能和模块进行划分,并能够有效地管理和组织代码。同时,包还提供了访问控制的机制,可以限制类和成员的访问范围,增强了封装性和安全性。
3.2 包的导入(Importing Packages)
包的导入是用来告诉编译器我们要使用的类或者接口所在的包。当我们在一个Java源文件中使用其他包下的类时,需要使用import
语句将这个类所在的包导入到当前的源文件中。
导入包的语法格式为:
import 包名.类名;
或者可以使用通配符(*
)导入整个包:
import 包名.*;
例如,导入某个包中的特定类的示例:
import java.util.ArrayList;
import java.util.List;
这样在代码中就可以直接使用ArrayList
和List
类,无需写完整的包名。
3.3 全限定类型(Fully Qualified Type)
全限定类型是指在代码中完整地指定一个类或接口的名称,包括包名和类名。
全限定类型的格式为:
包名.类名
例如,假设有一个类在包Exercise.PackageDemo
中:
package Exercise.PackageDemo;
public class MyClass {
...
}
在其他包中使用该类时,需要使用全限定类型:
Exercise.PackageDemo.MyClass myObj = new Exercise.PackageDemo.MyClass();
这样可以确保代码中引用的类是唯一的,避免了类名冲突的问题。
总结:包的导入使得我们能够方便地使用其他包下的类,而全限定类型则用于在代码中明确指定类或接口的完整名称,以避免命名冲突。
4 权限修饰符
在Java中,有四个权限修饰符用于控制类、方法和成员的可访问性:
public
(公共):公共修饰符是最开放的访问级别,表示该类、方法或成员可以在任何地方被访问。protected
(受保护的):受保护的修饰符表示该类、方法或成员只能在当前类、同一包内以及其他包中的子类中被访问。- 默认修饰符(不写修饰符):默认修饰符表示该类、方法或成员只能在当前类和同一包内被访问(即包私有)。如果没有显式指定修饰符,默认修饰符就会生效。
private
(私有的):私有的修饰符最为严格,表示该类、方法或成员只能在当前类中被访问,其他类无法直接访问。
下面相关的描述:
- 如果一个成员只想在本类中使用,就使用
private
修饰符。 - 如果一个成员只想在本类中和本包的其他类中使用,不写修饰符(默认修饰符)。
- 如果一个成员只想在本类中使用和本包中使用或者其他包的子类中使用,使用
protected
修饰符。 - 如果一个成员想在所有类中都可以使用,使用
public
修饰符。
这些权限修饰符可以帮助我们控制类和成员的可访问性,从而实现封装和限制访问的目的。
5 内部类
内部类是Java中定义在另一个类内部的类。它具有以下几种分类:
-
成员内部类(Member Inner Class):定义在类的方法外部的内部类。它与外部类有关联,可以访问外部类的成员变量和方法。在其他类中创建该类的对象时,可以使用以下格式:
外部类名.内部类名 变量名 = new 外部类().new 内部类();
-
局部内部类(Local Inner Class):定义在方法内部的内部类。它只能在所在方法内部使用,不能在其他类中直接使用。
-
匿名内部类(Anonymous Inner Class):是一种特殊的内部类,没有显式的类名。用于快速创建抽象类的子类对象或接口的实现类对象。匿名内部类的语法格式有三种形式:
-
创建抽象类的子类对象:
new 抽象类() { // 重写抽象类中的方法 };
-
创建抽象类的子类对象并调用重写后的方法:
new 抽象类() { // 重写抽象类中的方法 }.重写后的方法();
-
创建接口的实现类对象:
接口类型 变量名 = new 接口() { // 重写接口中的方法 };
-
使用内部类的好处是可以更好地组织和封装代码,实现类与类之间的更清晰的关系。内部类可以访问外部类的私有成员,并且提供了更多的封装选项和灵活性。
不使用匿名内部类时,如果给定一个抽象类,需要创建该类的子类对象,可以按照以下步骤进行操作:
- 创建子类,继承抽象方法。
- 实现抽象类中的所有抽象方法。
- 新建子类对象。
类作为方法的参数或返回值时,我们需要传递或返回该类的对象,而不是该类本身或其他类的对象。
静态代码块是定义在类成员位置的一段被大括号括起来的代码块。静态代码块在使用到一个类时会自动执行,只会执行一次,即第一次使用该类时立即执行。在同一个类中,静态代码块的执行优先级高于构造方法和main方法。
6 静态代码块
静态代码块(Static Block)是在Java类中使用static关键字定义的一段代码块。它在类加载过程中被执行,且只会执行一次。
静态代码块的语法格式如下:
static {
// 静态代码块中的代码
}
静态代码块经常用于初始化类的静态成员变量或执行一些与类相关的静态操作。它的特点如下:
- 当类被加载时自动执行,无需调用。
- 只会执行一次,即使创建多个该类的对象也只执行一次。
- 在静态代码块中可以使用静态成员变量和静态方法,但不能使用非静态的成员变量和方法。
静态代码块通常用于进行一些初始化操作,比如加载驱动程序、初始化静态变量等。示例:
public class MyClass {
static {
// 静态代码块中的初始化代码
// 加载驱动程序、初始化静态变量等操作
}
public static void main(String[] args) {
// 主方法
}
}
需要注意的是,静态代码块的执行顺序与其在类中的位置有关,先定义的静态代码块先执行。