**
Java基础笔记—第二篇(匿名对象、构造函数)
**
1. 数组
- 一维数组
a. 数组的声明(定义数组,并不为数组元素分配内存,因此在”[]“中不需要指出数组的元素个数)
b. 创建和赋值(创建并不是定义数组,而是在定义数组之后,为数组分配内容,同时对数组进行初始化)
声明:数据类型 数组名[] /数据类型 []数组名
创建:数组名 = new 数据类型[size]
赋值:直接赋值并定义数组大小 int a = {1,2,1,3,4};
大小:数组名.length
- 多维数组
二位数组分配空间第二维可以为空,但是第一维必须分配内存
二位数组第二维可以不等长 int a = {{1},{1,2},{1,2,3}}
2. 类和对象
Oop:Object Oriented Programming 面向对象编程 。
类:对象的蓝图,生成对象的模板,是对一类食物的描述。
对象:是实际存在的该类事物的每个个体,也成实例。
过程其实就是函数,对象是将函数等一些内容进行了封装。
3. 匿名对象、匿名类
匿名对象是没有名字的实体,也就是该实体没有对应变量名的引用。
- 使用场景:当对方法只进行一次调用的时候,可以使用匿名对象;当对象对成员进行多次调用时,不能使用匿名对象,必须给对象起名字。
- 特征:只能调用一次;只在堆内存中开辟空间,不存在栈内存的引用;每次创建的匿名对象都是不同的对象。
匿名类是不能有名称的类,所以没办法引用它们,必须在创建时,作为new语句的一部分来声明。相当于在定义类的同时再创建这个类的实例。
- 匿名类的声明是在编译时进行的,实例化在运行时进行,这意味着如果for循环中有一个new语句会创建相同匿名类的几个实例,而不是创建几个不同匿名类的一个实例。
- 特点:必须继承一个或实现一个接口,而不能显示的使用extends和implements,没有父类;没有构造方法,通过new <父类名>创建对象,匿名类的定义与创建对象是同时进行的;匿名类只能一次性的创建,并有父类句柄持有;匿名类不需要初始化,只有默认的构造方法。
- 规则:匿名类内部类不能是抽象类(因为系统在创建匿名类内部类时,会立即创建内部类的对象);匿名内部类不能定义构造器(因为匿名内部类没有类名),但是内部类可以实例化初始化块;不能定义静态初始化块(内部类中不能定义任何静态的东西);不能在匿名类里面定义接口。
public class MainObject {
public static void main(String[] args) {
AllBehaviors allBehaviors = new AllBehaviors() {
@Override
public void walk() {
System.out.println("我在走路!");
}
@Override
public void play() {
System.out.println("我在玩!");
}
};
allBehaviors.play();
allBehaviors.walk();
}
}
interface AllBehaviors {
void play();
void walk();
}
匿名类和匿名对象区别:
a. 匿名对象还是一个对象,他必须有已经写好的成员变量、属性、方法。
b. 匿名类在声明它的对象时,才进行代码构造。
c. 一个对象只使用一次的时候,通常使用匿名对象。
d. 比如我们需要一个监听类,并且在实例化这个监听类时,才需要实现这个监听类内部的方法,使用匿名类就比较方便。
4. 成员变量、成员函数、局部变量、私有成员
- 成员变量:其实对应的就是事物的属性
- 成员函数:其实对应的就是事物的行为
- 私有成员:其他类不能直接创建对象访问,只有通过本类对外提供具体的访问方式【setXXX()和getXXX()】来完成对私有的访问。属性是用于存储数据的,直接访问容易出现安全隐患。
- 主函数:主函数的存在仅为该类是否需要独立运行,如果不需要,主函数是不用定义的。
成员变量和局部变量区别:
a. 位置:成员变量定义在类中,局部变量定义在方法中、参数上、语句中;
b. 生命周期:成员变量在这个类中有效,局部变量只在自己所属的大括号有效,大括号结束,局部变量失去作用域。
c. 内存:成员变量存在于堆内存中,随着对象的产生而存在,消失而消失;局部变量存在于栈内存中,随着所属区域的运作而存在,结束而释放。
d. 初始值:成员变量有默认初始值;局部变量没有默认初始值,使用之前需要赋值,否则编译器会报错。
5. 构造函数
构造函数用于给对象进行初始化(可以有多个构造函数,用重载体现,用参数列表区分)。普通函数可以和构造函数同名,但是必须带有返回值。
特点:
a. 函数名称和所在类的名称相同;
b. 不需要定义返回值类型,没有具体的返回值;
c. 在对象被创建时,自动执行;
d. 构造函数不能被显示的调用。
作用:
a. 给创建的对象建立一个标示符;
b. 为对象数据成员开辟内存空间;
c. 完成对象数据成员的初始化;
当用户没有显示的去定义构造函数时,编辑器会为类生成一个默认的构造函数—”默认构造函数“—不能完成对象数据成员的初始化,只能给对象创建一标识符,并为对象中的数据成员开辟一定的内存空间,如果在类中自定义了构造函数,那么就不会有默认构造函数啦。
6. 静态代码块>构造代码块>构造函数>普通代码块的执行顺序
- 静态代码块—在Java类中(方法中不能存在静态代码块)使用static和{}声明的代码块。
a. 执行时机:在类加载时就运行啦,而且只运行一次,并且优先于各种代码块以及构造函数,若存在多个,按顺序执行。
b. 作用:有需要在项目启动时就执行(例:项目启动时需要加载的很多配置文件等资源)。
c. 静态代码块不能存在于任何方法中。
d. 普通方法:是通过加载类,然后new出实例化对象,通过对象才能运行方法,而静态代码块只需要加载类后就执行。
e. 静态方法:在类加载时,静态方法也已经加载,但必须通过类名或对象名才能访问,相比于静态代码块,静态代码块是主动运行的,而静态方法是被动运行的。静态代码块的存在在类加载时就自动运行啦,而不管是普通方法还是静态方法都不能自动运行。
f. 静态代码块不能访问普通变量(普通变量只能通过对象来调用,不能放在静态代码块中)。
- 构造代码块—在Java类中使用{}声明的代码块。(和静态代码块相比少了static关键字)
a. 执行时机:在创建对象时调用,每次创建对象都会调用一次,并且优先于构造函数。但是构造代码块的执行依托于构造函数,如果不实例化对象,代码构造块是不会执行的。
b. 作用:和构造函数类似,都能对对象进行初始化,并且只要创建一个对象,构造代码块就要执行一次;但是反过来,构造函数并不一定每次创建对象时都执行(在多个构造函数的情况下,执行哪个构造函数主要看建立对象时的传参,传参不同,则初始化使用对应的构造函数)。利用这个特性,可以做诸如统计创建对象的次数的统计。
- 父类和子类的执行顺序:
父类静态代码块 > 子类静态代码块 > 父类构造代码块 > 父类构造函数 > 子类构造代码块 > 子类构造函数
public class CodeB {
static{
System.out.println("静态代码块");
}
{
System.out.println("构造代码块");
}
public CodeB (){
System.out.println("无参构造函数");
}
public void sayHello(){
{
System.out.println("普通代码块");
}
}
public static void main(String[] args) {
System.out.println("执行了main方法");
new CodeB ().sayHello();;
System.out.println("---------------");
new CodeB ().sayHello();;
}
}
执行结果:
静态代码块
执行了main方法
构造代码块
无参构造函数
普通代码块
------------------
构造代码块
无参构造函数
普通代码块
public class Test {
Person person = new Person("Test");
static{
System.out.println("test static");
}
public Test() {
System.out.println("test constructor");
}
public static void main(String[] args) {
new MyClass();
}
}
class Person{
static{
System.out.println("person static");
}
public Person(String str) {
System.out.println("person "+str);
}
}
class MyClass extends Test {
Person person = new Person("MyClass");
static{
System.out.println("myclass static");
}
public MyClass() {
System.out.println("myclass constructor");
}
}
执行结果:
test static
myclass static
person static
person Test
test constructor
person MyClass
myclass constructor