5.JAVA面向对象
什么是面向对象
什么是面向过程:
面对一个需要解决的问题时,注重的是解决问题的步骤。第一步做什么,第二步做什么。在程序中相当于一个方法内按顺序执行代码的一个流程。
同样是解决一个问题,面向对象的角度是将问题抽象成对象的形式。通过分类的思维方式,将问题分成几个解决方案的对象。给每个对象赋值属性和方法,对每个对象的细节进行面向过程的思维,执行自己的方法来解决问题。
面向对象的实质是:以类的方式组织代码(模板),以对象的形式封装数据(具体化)。
面向对象的重要思想是抽象。
正如世界一样,充满了多种多样的事物。把有相同特性的事物归纳起来组成一个类叫做抽象。
面向对象的特性:
-
封装:将具体的事物封装成对象后,对外隐藏对象中的逻辑代码。只留一个入口从外面调用对象。
-
继承:让某个类型的对象获取另一个类型对象的属性和对象。无需重新编写原来类的代码,实现子类继承父类的能力。
-
多态:在同一个类中不同对象使用该类的方法时,呈现的效果却大不相同。
类和对象的创建
类和对象的关系:
类是一个抽象的数据类型,对某一个事物进行描述和定义。将相同特征的事物总和在一起才称为类,并不能代表一个具体的事物。
例如:Student类、Teacher类一样,具备某一事物相同的属性和方法。
对象表示具体的一个事物,在一个类当中可以有多个不同的对象。
例如:张三这个人是Student类中可以被确定的具体实例。就像生活中每一个人一样,具备不同的特点和功能,而不是抽象的概念。
在创建类和对象之前,要有清晰的结构思维
创建一个只有main方法的主类,专门用来当做代码运行的入口测试类或启动类。
在另一个窗口创建一个只有public关键字的类来当作功能类(也叫做抽象的模板)。每当需要新增别的功能时,可以不修改原数据进行扩展操作。
以创建Person类的代码实例进行分析:
创建一个共同特性为Person的一个类 在这个种类的类当中可以定义最常见的两个变量name和age(在类中也叫成员属性)。
在这个Person类当中可以将创建的方法称之为实例方法,相当于拥有的共同特征。
若要使用这个类 就必须在主方法内进行实例化操作:
首先将抽象转换为具体,也叫做类的实例化。在这个案例当中创建了Sum和John这两个不同的人(对象)。
由于类只是一个模板,属性只有默认值。将每个对象中的属性进行定义,每个对象拥有不同的属性。称为对象的形式封装数据。
需要注意的是:
-
这两个类不在同一个Java文件中
-
一个类可以包含多个对象
-
对象的模板中只能声明属性,不能将属性初始化。
创建对象的内存分析
创建类和对象时,会用到Java内存当中的栈、堆、方法区。
类和对象分别存放的位置:
-
创建的类会被存放在方法区中
-
每个对象的引用变量存放在栈当中
-
定义的对象属性和方法会被存放在堆当中
利用代码案例分析原理图:
-
当代码执行到主类时,会在方法区中生成main方法和其他相关的属性,将main方法压栈在内存中。
-
使用new操作符创建对象之前,将Pet类及属性和方法载入方法区当中作为对象模板。
-
创建对象时,则会在栈内存当中生成这个对象的引用变量,用来指向堆内存中对象的地址。
-
当给对象属性和方法进行定义时,通过方法区给出的Pet类模板将定义的属性存放在堆内存中。
-
当创建另外一个不同的对象时,将上述步骤重复执行后,在堆内存中生成一个新的对象块。
需要注意的是:方法区除了存放创建的方法数据以外。还有一个静态方法区,用于存放包含static修饰符的方法,便于和类一起加载。
二、Java构造方法
当一个抽象类被创建对象后,会在.class编译文件中自动生成一个修饰符为public的方法。称为构造方法。
构造方法的特点:
-
方法名与类名相同。
-
没有返回值。
-
只要使用该类的new操作符,便自动生成。
-
当对象引用被创建后,程序进行运行便会执行构造方法中的代码块
构造方法的类型
无参构造
有参构造
有参构造中含有形参所对应的是在主方法括号内可以输入该属性的值将其传递给这个构造方法。
当对象被创建后 该构造方法已经存在 所以可以输出参数
this 关键字
此操作可以访问当前类的属性和方法
this的用法:
这是在类当中的操作
将此类的操作调用并打印:
在主方法中,创建该类的对象后通过调用该类的方法输入实参后,便可有输出this操作后的结果
get和set方法
set方法可以给自定义类私有属性进行初始化操作或赋值
get方法在其他包的类中使用get方法将私有属性进行输出
创建set 和 get:
-
首先创建一个set方法 用于成员变量值的设定
2.再通过get方法 将设定的变量值返回给成员属性
设置了set方法和get方法后 在主方法中进行调用
-
使用接口
使用封装这一功能 使程序变得结构化 代码变得更容易理解 对于之后功能的扩充有一定的帮助。
三、Java实例方法以及特性
实例方法
方法是语句的集合,执行某种功能
用来解决一类问题的有步骤排序的语句组合
方法包含于类和对象中
在程序里创建方法,用于在其他地方被引用
方法的定义
方法相当于一个函数,一段用来实现特定功能的片段
方法的语法结构:
public static void main(String[] args){};
第一段:修饰符 用来告诉程序如何调用该方法 声明了该方法的访问类型
第二段:返回值类型 有些方法会返回数据 有些方法没有返回值 则为void
第三段:方法名 与参数列表共同称为方法签名
圆括号内:形式参数 包括参数的类型 执行顺序以及参数的个数 是用来被调用的
花括号内:方法体 包含具体的语句 定义方法的功能
return 方法体最后的结束语句 加上存储数据的变量 返回给主方法执行
方法的调用
调用方法的基本语法:
对象名.方法名(实参列表)
例:method.method(a : 1,b : 2);
方法的类型:
-
静态方法(类方法)
-
非静态方法(实例方法)
静态方法:
方法的修饰符中含有static 是隶属于类的方法,与对象无关可直接在main方法内调用
使用语法:类名.方法名调用,在本类中使用可以省略类名
可以直接调用的原因:含static修饰符的方法是和类一起加载的,所以在同一片段中可以直接调用方法
实例方法:
方法没有修饰符在需要调用时 必须先创建一个对象 才能调用
不可以直接调用的原因:
实例方法是针对与对象的 必须先创建类的对象名以此作为调用实例方法的入口才能进行调用
方法的参数传递
在调用方法时,向形参传递参数的过程称为参数传递。
编程语言传递数据的方式有两种:值传递和引用传递。
变量类型:在Java中,指向基本数据的变量称为原始变量。指向对象的变量称为引用变量。
值传递:在Java中,基本数据类型创建变量时,直接将变量的值存在了内存当中。当使用基本类型作为方法的实参时,即使将实参传递给方法的形参也不会改变实参的数据。
引用传递:在Java中,当方法内创建引用变量指向方法外变量的地址时,方法内的变量则会改变方法外的变量。
方法返回值类型的两种情况:
-
当方法有返回值时,输入每个实参的值代入方法
int number = method(a:1,b:2);
-
当方法的返回值为void时,没有返回类型
实例方法的相关特性
方法的重载
在一个程序里,可以使方法名相同,参数列表不同的函数存在,便可以实现传递数量不同类型不同的参数
满足下列条件才是重载,某些条件不满足则会报错:
1.方法名相同
2.形参的个数、类型和顺序不相同
3.返回值不同
在两个相同的方法中,程序会根据参数的类型、数量和排列顺序自动匹配适合的方法运行,一个程序里可以拥有多个相同结构的方法。
举例:
主方法内的输出语句为:
则会自动匹配含有两个参数的方法
public static int max(int a,int b){};
若输出语句为:
就会运行形参有三个参数的方法
public static double max(int a,int b,int c){};
可变参数
当遇到需要传递任意数量的参数时,使用重载方法会使程序变得繁琐复杂
便可以用到可变参数
语法格式:
public static int Method(int... a){};
语法规范:
-
一个方法只能写一个可变参数
-
调用可变参数的类型只能定义一种
-
可变参数只能写在普通参数的最后
递归
在常规程序中若需要调用一个方法是在主方法内调用方法,当需要解决一些复杂的运算,便可以使用递归的原理来编写。
前提条件为计算基数较小的值,传递值过大会影响程序的性能或导致计算机的内存崩溃
递归的原理:一个方法内返回值为方法本身,若没有终止运行的条件,方法将会循环调用自己,就像for循环不写布尔表达式一样
递归的结构:
-
递归头:在什么时候不调用自身,边界条件
-
递归体:什么时候调用自身,递归公式
若没有定义条件,程序进入死循环直到内存崩溃
递归案例:计算1加到1000的结果是多少
编程思路:
1 + 2 + 3 + …… + 1000 = ?
把1000放在最前面 1放在最后
1000 + 999 + 998 + …… + 1
当加到1时,程序结束
设传递值为n,当n = 1000
得出1000 + (1000 - 1)
当n = 999 得999 + (999 - 1)
找到规律后便可以推导出程序
return n + f(n - 1);
这段递归语句并没有在程序里呈现计算过程
通过以下简易的内存分析图解释:
命令行传递参数
在IDEA编程中调用方法来实现某些算法时,需要通过main方法向方法传递参数实现。
如果不从IDEA内部传递也可以从命令标识符进行传递
案例代码:
传递main方法内的字符串数组类型
用命令行指令传参 不从程序内进行传递
在案例Demo4类文件的路径下打开命令行窗口
找到程序用命令行编译成源代码
运行程序的步骤:
-
切换到IDEA项目根目录下,直接运行程序会找不到类文件
-
必须要输入完整的路径一直到.Java文件
-
运行程序
传递参数:
四、Java面向对象的特性
封装
在面向对象的设计方法中,用于对代码细节进行包装和隐藏的方法。
可以将封装理解为一个保护措施,防止被外部类的代码随机访问。
访问代码的条件:只通过一个接口进行访问。
封装的功能:将程序需要执行的代码流程进行包装和隐藏,同时降低代码的耦合性,便于代码的日常维护和扩展。
封装的特点
-
提高了程序的安全性,保护数据
-
统一接口
-
隐藏代码的细节
-
提高代码的易维护性和扩展性
this 关键字
此操作可以访问当前类的属性和方法
this的用法:
这是在类当中的操作
将此类的操作调用并打印:
在主方法中,创建该类的对象后通过调用该类的方法输入实参后,便可有输出this操作后的结果
Private 关键字
与public关键字相对立,俗称属性私有。
与public不同的是,无法直接访问或修改该对象的属性。
Private是访问权限最窄的修饰符,禁止跨包访问。
语法:关键字后为变量的代码结构
例:
private String name;
当一个类当中存在private关键字,那么后面的成员属性将不能直接访问
若要进行访问就必须创建一个接口
创建接口的方法
创建set 和 get:
-
首先创建一个set方法 用于成员变量值的设定
2.再通过get方法 将设定的变量值返回给成员属性
设置了set方法和get方法后 在主方法中进行调用
-
使用接口
使用封装这一功能 使程序变得结构化 代码变得更容易理解 对于之后功能的扩充有一定的帮助。
继承
继承的实质指的是一个类获取到另一个类对象属性的方法,将类进行抽象化,并按照一定结构划分。
继承被用来对程序进行扩展,可以在原有的程序中继续编写新添加的代码。提高了工作效率,使代码结构分明。
继承的特性:
子类(派生类)继承父类(基类)的属性和方法,具备父类的所有特性。
单继承性:一个父类可以拥有多个子类,但每一层子类只能存在一个父类的关系。
extends 关键字
给类添加一个继承的关系
语法:
public class son extends parent(){};
son(子类)继承parent父类
注意事项:
-
默认情况下父类的成员属性和方法都可以被子类访问
-
被final修饰的类(终极类)不能被子类继承
-
创建子类对象时会创建父类对象先执行父类构造器再回到子类构造器
-
父类的私有属性和方法不能被子类直接访问
-
父类的构造方法不参与子类的继承,父类的构造方法是独立
-
父类中被final修饰的方法不能被重写
-
子类创建的上转型对象不能访问子类的属性和方法,会失去在子类中新添加的功能
权限修饰符四种表达方式
public 公共 表示最高权限 可以跨包跨类访问
Protected 受保护的 允许当前类和此类的子类访问,除了子类其他类不能跨包访问
Default 默认的 只能在当前包当前类访问,其子类和其他包不能访问
Private 私有的 权限最低,只能在当前类中访问
super 关键字
super关键字是用于指向父类对象的操作
注意事项:
此操作可以在子类方法中调用和访问其父类的属性和方法
用于在子类构造器中标识访问父类的构造器
访问父类属性和方法的用法:
1. 创建一个父类
在定义类的语句中,含有注释的这一段代码是默认执行的,因为所有的类都存在于Object类当中
-
为了方便表示子类和父类之间的关系,创建一个与Parent类有继承关系的类
在这个测试方法中 就实现了使用super关键字访问父类当中的相关数据
加载父类的构造方法:
-
显示父类的无参方法
-
显示子类的构造方法
-
用主方法创建子类的对象时
创建子类的对象之前 程序会提前加载类的构造器 如果此类与其他类具备继承关系 则会优先加载其父类的构造方法
但是加载的构造方法要么是无参数的构造,要么是有参的构造,两者只能取其中一个
super与this的区别:
-
访问的对象不同,super是访问其父类的构造方法、实例方法和属性
-
使用条件不同,super必须在有继承关系的类中使用
super的注意事项:
-
当创建含有继承特性的对象时,会将其父级的构造器一同加载
-
创建对象的构造器具有唯一性,要么调用自身类的构造器,要么调用父类的构造器
-
继承性,当其父类当中没有无参构造器,那么子类的无参构造将会无法创建
方法的重写
在满足继承关系的前提下,子类对父类方法函数进行修改或覆盖的操作。
满足重写的条件:
子类重写的函数与父级类的函数的结构相同(函数名 参数类型),函数内代码不相同
访问修饰符为private的方法不能被子类重写
子类重写的方法访问级别不低于其父类方法的访问级别
父类的方法被final修饰不能被重写
子类不能重写父类的静态方法,但是可以覆盖。覆盖方法:与重写方法不同,没有@Override注解,与父类同名的方法为两个完全独一的方法
重写方法的操作:
在两个类确定谁继承谁后,在子类中创建一个与父类相同名字相同类型的方法,结果则是子类覆盖了父类的方法
Man类继承People类
多态
不同类型的对象指向相同的类,在程序运行时实现不同功能的方法
多态相当于在同一接口中使用不同的实例化执行不同的操作
多态的用处:使程序具有可扩展性,可以实现不同对象的通用性
多态的优点:1. 可替换性 2. 可扩展性 3. 接口性 4. 灵活性
多态的前提条件:
-
继承
-
子类重写父类
-
父类的引用指向子类
由于多态提高了创建对象的灵活性,可以使用不同的引用类型
创建对象的格式:
Man boy = new Man();
左边的子类的引用类型指向子类,也可以为有关联类(父类)的引用
右边的实际类型是确定的,一般指向是哪个类的
在Man类继承People类的案例中:
可以看出虽然创建的对象不同,但是结果都是子类的
原因:由于子类重写了父类的方法,不管是父类的引用还是子类的引用使用的都是被子类覆盖的方法。若使用的方法是各自独有的,则会导致结果的不同
多态的注意事项:
-
重写的方法仅限于非静态方法,因为静态方法调用是哪个类就是用哪个类的方法
-
在多态中子类可以调用自己的方法,重写父类的方法
-
父类不能直接调用子类独有的方法
instanceof 关键字
用于判断对象是否属于这个类的实例。结果为布尔表达式,属于为true,不属于为false
判断公式:a instanceof A
a 对象 A 类
使用instanceof的判断条件:
首先a对象的类与A类是否有继承关系,如果没有关系,则编译报错
实例体现:创建一个父类Person、两个子类Student和Teacher
-
根据instanceof的判断条件可以得知:
若当前判断对象的从属类跟判断的类一样则表示为true,若当前判断对象的从属类跟判断的类有直接的继承关系,也属于该对象的实例所以结果为true
-
根据对象所指向的实际类型判断:
若对象的引用类型指向的类不是表达式中的类,则判断为false
-
根据继承特性判断:
若对象的类与判断的类没有继承关系,程序在运行时会编译错误
引用类型转换
与基本数据类型的转换方式相同,把子类看成是低一级的类,父类看成是高一级的类。若要把高一级类的对象转换成低一级则需要强制转换,低转高为自动转换
创建父类Person和子类Student的案例:
父类拥有Per方法,子类拥有Stu方法
高转低
由于创建的student对象类型为父类,要强制转换成子类的引用类型才能使用子类的方法
低转高
对象类型为子类,自动转换为高一级的引用类型可以直接访问父类的方法。但是会失去对象转换前子类方法的访问的权限
抽象类
在面向对象的概念里,所有的对象都是通过类来描述的。如果反过来,并不是所有的类都可以创建对象的。如果一个类中没有用来描述对象的内容就是抽象类。
抽象类虽不能创建对象,但是具备普通类的其他功能,可以包含成员变量、成员方法和构造器。
特性:
抽象类的方法必须被继承才能拿来使用,一个类只能继承一个抽象类。
抽象类自身不能实例化,必须通过其子类进行实例化
抽象类不能被final修饰
abstract修饰符
Java当中使用abstract修饰符来定义抽象类
public abstract class Abstract Demo{};
抽象类的定义
抽象类可以包含自己的属性、方法和构造器,但不能通过自身的对象拿来使用
抽象方法
abstract不仅可以修饰类,还可以修饰方法。
注意点:
-
抽象方法不能被定义,所以需要通过子类重写才能进行定义
-
若一个类中包含了抽象方法,那么这个类也必须定义为抽象类
子类继承抽象类
继承抽象类的前提:
-
重写抽象类的抽象方法,继承抽象类的子类中必须有对抽象类中抽象方法的实现
-
这个类也声明为抽象类
若继承抽象类的子类也声明为抽象的,那么该类也不能创建对象
抽象类对象上转型对象,实例是子类的,对象类型是抽象的,因此抽象类对象也会失去在子类中的一些功能
抽象类继承抽象类
当抽象类的继承对象也是抽象类,其抽象子类也包含抽象类的所有特性,除了可以定义抽象方法和非抽象方法,也可以重写抽象父类的抽象方法,以便于相关子类不用强制重写抽象类
适配器引用
当抽象类中有多个抽象方法,若要被子类继承,就必须全部重写
为了让子类只需要继承个别抽象方法,就需要通过一个适配器类来对重写的抽象方法进行空实现
创建一个抽象类
package com.JavaSE.Abstract;
public abstract class Student {
/*
创建多个抽象方法
*/
public abstract void study();
public abstract void makeMoney();
public abstract void work();
public abstract void getMarry();
}
创建一个适配器类
作为抽象类的一个适配器是一个普通的类,适配器类继承抽象类
并对其子类实现的抽象方法进行空实现(方法体中不用写任何信息)使得继承抽象类的子类不需要依次重写不需要的抽象方法。
就像电脑的适配器一样,适配器一头继承抽象方法,另一头继承抽象的功能子类
public class StudentAdapter extends Student{
@Override
public void study() {
//空实现 代替实现功能的子类进行重写
}
@Override
public void makeMoney() {
}
@Override
public void work(){
}
@Override
public void getMarry() {
}
}
继承抽象类的子类
import com.JavaSE.Abstract.StudentAdapter;
//使用适配器类需要继承
public class Man extends StudentAdapter {
//子类继承适配器后可以只重写业务中需要的抽象方法
@Override
public void study(){
System.out.println("一个家庭顶梁柱需要有足够的知识储备");
}
}
接口
接口是一个Java抽象类型的集合。
一个类继承了一个接口,从而来继承这个接口中的所有抽象的方法,使Java具有多继承性。
接口是用来被实现的
接口的特性:
-
被接口定义的属性为常量,不得修改。隐式指定为 public static final
-
接口定义的方法为隐式抽象的,不能写入其内容。隐式指定为 public abstract
-
接口可以声明方法,但不能实现
-
接口定义的抽象方法和常量只能是public 或缺省这两种访问修饰符
定义接口并实现
interface关键字
接口不是一个类,不能写入方法的内容。
接口定义变量
-
在接口中可以声明变量,变量的类型可以是各种类型。
-
必须是public static final所修饰
-
灰色部分可以忽略不写
接口定义方法
-
接口跟普通类一样,可以定义多个方法,但是方法的类型必须是抽象的。
-
public abstract所修饰
在jdk1.8版本的新特性:接口支持使用default权限的方法
default void ran(){};
实现接口方法
implement关键字让一个类实现这个接口
实现前提:1. 必须重写接口的所有方法。2. 该类也是被abstract修饰符修饰
需要注意的是:若该类实现了接口,其性质也转变为抽象类,不能被直接实例化
接口的继承
子类接口对父类接口中的抽象方法和常量进行继承,与父类和子类一样,除了继承父类的所有功能之外,子类接口也可以定义属于自己的特殊实例方法或常量
接口中常量和静态方法的创建
public interface interfaceImp{
//接口java系统默认只能定义静态常量 常量的修饰符只能是public abstract可以省略
String feature = "接口的特征";
//接口只能定义抽象方法,接口只能被实现或被继承 public static final可以省略
void absMethod();
}
子类对接口的继承 子类必须是个接口 继承父类接口的方法
//继承接口的类型必须是接口
public interface InterfaceImp extends Interfaces {
//可以重写父类接口中的抽象方法 但是修饰符为default
@Override
default void absMethod() {
System.out.println("这是重写接口的抽象方法");
}
}
对接口实现的子类
//通过implements实现类来访问接口的属性
public class Son implements InterfaceImp {
@Override
public void absMethod(){
System.out.println("修饰符为public对接口方法的实现");
}
public void realization(){
System.out.println(feature);//打印常量属性
absMethod();//调用方法
}
}
总结
接口和普通类的相同点:
-
接口可以被子类接口继承
接口和普通类的不同点:
-
接口不能实例化
-
接口没有构造方法
-
接口中定义的方法都是抽象类型的
-
接口不是被继承,而是被实现
-
接口具有多继承性,一个类可以实现多个接口
内部类
在Java中,还存在一些比较特殊的创建类的方法,类似于类当中的嵌套操作。
内部类局限于外部类,只在外部类之中被访问
根据不同的嵌套操作进行分类
成员内部类
静态内部类
局部内部类
匿名内部类
内部类的特点:
-
内部类可以使用public protected private 缺省,四种访问修饰符
-
内部类可以定义成abstract final static
-
内部类没有Java源文件,只有class字节码文件
成员内部类
在A类中再定义另外一个B类,A类为B类的外部类,B类为A类的内部类
案例:
成员内部类跟普通类的共同点,可以创建对象。
对于内部类方法调用与外部类的区别:需要通过外部类的对象进行内部类的实例化。
通过外部类对象创建内部类的构造方法并赋值给Outclass.Inclass引用类型的内部类对象in
内部类的特性:内部类可以访问外部类的私有属性或方法
访问私有属性的案例:
静态内部类
可以用public static关键字修饰的类称为静态内部类
创建条件:必须在一个类之中定义
案例:
静态内部类中内部类可以直接调用外部类的静态属性和方法,但不能调用内部类的非静态变量和方法
静态内部类注意事项:在静态内部类中不可以定义抽象方法
局部内部类
和局部变量特性相似,作用域只限于方法当中的类,因此只能在这个方法当中被使用
案例:
局部内部类中不可以定义静态变量和属性,所有的变量和属性这个方法之外不能被其他类调用
匿名内部类
不需要定义对象的名字就可以实现调用该类属性和方法的操作,可以更方便而简洁的去访问类的属性或方法,而不用创建太多对象类型
匿名内部类的特征
-
匿名类的对象没有对象类型
-
匿名类经常用于接口或抽象方法的实现,可以减少接口和抽象类实现类的定义
-
匿名类属于它实现的父级类型
案例:
Static关键字解析
static关键字可以用来修饰类、成员变量和成员方法。
被static修饰的成员变量称为静态变量。
用来修饰方法则称为静态方法
静态属性、静态方法、非静态属性和非静态方法的各使用方法
静态代码块中内容的定义规范
-
静态代码块只能写在类当中
-
静态代码块中可以访问类中的静态变量和静态常量
-
静态代码块中可以定义局部变量和局部常量
-
可以定义局部类
-
不可以访问或定义实例变量和方法,但是可以在局部类当中定义
代码演示
public class DemoClass {
public static String average;//声明静态变量和常量
public static final String CONSTANT;
static{
//给变量和常量赋值
average = "这是静态变量";
CONSTANT = "这是静态常量";
//定义局部变量和常量
String local = "这是局部变量";
String LOCAL_CONSTANT = "这是局部常量";
//定义一个局部类
class LocalClass{
String localAverage = "这是局部类变量";
String localMethod(){
return "这是局部类的方法";
}
}
//访问局部类中的变量和方法
System.out.println(new LocalClass().localAverage);
System.out.println(new LocalClass().localMethod());
}
}
静态代码块的内存运行机制
静态代码块与对象无关,所以不能在静态代码块中出现this或super与对象相关的关键字,并且静态块跟类同时加载,所以静态代码块中的内容不管调用多少次也只能执行一次,并且比所有构造器加载得早
在类产生之前写入一些初始化参数、对静态变量和常量进行赋值,以及调用静态方法
静态导入包的操作