1. 面向对象
面向对象和面向过程的区别:
面向过程:将问题分解成步骤,然后按照步骤实现函数,执行时依次调用函数即可。数据和对数据的操作是分离的。
面向对象:将问题分解成对象,描述事物在解决问题的步骤中的行为。对象与属性和行为是关联的。面向对象的三大特性是:封装、继承、多态。
优缺点:
面向过程的优点是性能高,适用于高性能要求的场景;缺点是不容易维护、复用和扩展。
面向对象的优点是容易维护、复用和扩展,可以设计出低耦合的系统;缺点是由于需要实例化对象,因此性能比面向过程低。
对象与类:
对象:对象在实现世界中可以明确标明的实体,对象有自己独特的状态与行为。状态是静态的,由对象的数据域集合组成;行为是动态的,由对象的方法的集合组成。
类:具有某些相同特性的对象的集合,是一个抽象的概念,用于定义对象数据域与方法。从一个对象可以创造多个类,创建对象的过程称为实例化。
2. 构造方法
功能:创建一个新的对象并进行初始化。
声明:构造方法的名称必须与其所在的类一致,构造方法允许重载。
调用:通过关键字new调用操作方法,用以创建新对象(new会在堆内存中创建一片空间,用于存储该类对象,然后通过构造方法初始化)
默认构造方法:当类中没有显式声明任何构造方法时,会默认隐式声明一个无参数且没有方法体的默认构造方法。
特点:
1)方法名与所在类名相同;
2)没有返回值,不需要声明返回值类型,包括void;
3)通过new关键字调用;PS:可以通过this(args)在构造方法中调用本类已声明的构造方法,通过super(args)在构造方法中调用超类已声明的构造方法。
/**
* @description 账户类
* @author Rock
* @date 2021/06/30
*/
public class Account{
// 用户名称 name
String name;
// 用户账户
int accountId;
// 全参构造方法
public Account(String userName, int userAccountId){
this.name = userName;
this.accountId = userAccountId;
}
}
3. 静态与实例
Java中的类成员(变量、方法)可以区分为静态的(通过static关键字修饰)与实例(无static关键字修饰)。
变量:
1)局部变量:
声明于类中方法体内部的变量,其生命周期为变量声明~方法体执行结束,作用域为方法体中变量声明之后的代码段。
2)静态变量:
声明于类中方法体之外的变量,通过关键字static修饰,其生命周期为类加载开始到程序执行结束,作用域为程序的所有部分。
3)实例变量:
声明于类中方法体之外的变量,没有关键字static修饰,其生命周期为实例创建开始到程序执行结束,作用域为程序自该实例创建后的部分。
方法:
1)静态方法:
在类中声明的通过static关键字修饰的方法,自类(.class字节码文件)加载后即可调用。
2)实例方法:
在类中声明的不通过static关键字修饰的方法,自声明该方法的类创造实例后即可调用。
外部调用(一个类中调用另一个类)与内部调用(在本类中调用):
1)局部变量只允许在方法体内进行调用。
2)静态类变量允许外部调用,不同类中需要通过 【类名.类变量名】进行调用,也可以通过该类的实例调用,但这需要首先创建实例,因此不推荐。静态类变量也允许内部调用,同一类中通过 【类变量名】直接调用。注意:静态方法只可以访问静态成员(变量+方法),因为在使用静态方法时不一定创建了实例。
3)实例类变量允许外部/内部调用,但访问前必须先创建该类的实例,通过该实例访问实例成员,访问方式为 【对象名.实例成员名】。注意:实例类变量既可以访问静态类变量,又可以访问实例类变量(需要先创建实例)。
/**
* @description 静态与实例
* @author Rock
* @date 2021/05/15
*/
public class Tests{
// 静态变量i
static int i = 100;
// 实例变量 j
int j = 200;
// 静态方法iprint
public static void iprint(){
System.out.println("i = " + i);
}
// 实例方法jprint
public void jprint(){
// 局部变量k
int k = 50;
System.out.println("j = " + j);
// 调用静态方法iprint()
iprint();
System.out.println("k = " + k);
}
}
PS: 如何判断一个类成员应该被定义成静态的还是实例的呢?取决于类成员是否依赖于具体实例。如果一个类成员依赖于具体实例,则该类成员应该被定义成实例的类成员(例如String实例str 的length属性),否则就应该被定义成静态的类成员(例如Math中的所有方法都是静态的)。
4. 代码初始化块
代码初始化块属于类成员,在类加载时(静态代码块,通过关键字static修饰)或创建对象(实例代码块)时会隐式调用代码块,使用代码块的优点在于提供了在特定时间节点执行代码的可能(例如日志)。
分类:
静态代码块:类加载时执行,通过static修饰;由于静态代码块在类加载时执行,其只会执行一次。
实例代码块:创建实例时执行;每次在创建实例时都会执行实例代码块与构造器,实例代码块先于构造器执行。
public class InitBlock {
// 静态代码块
static {
System.out.println("执行静态代码块");
}
// 实例代码块
{
System.out.println("执行动态代码块");
}
// 实例变量i
int i;
public InitBlock(int input){
this.i = input;
System.out.println("执行构造方法");
}
public static void main(String[] args) {
InitBlock ib = new InitBlock(10);
}
}
单个类的代码初始化块执行顺序:
【静态代码块】 先于 【实例代码块】 先于【构造器】
以上代码的执行结果为:
存在继承关系的代码初始化块执行顺序:
1)按照从父类到子类的继承顺序,依次执行每个类的静态初始块;
2)按照从父类到子类的继承顺序,依次先执行父类的实例代码块以及构造器,然后再执行子类的实例代码块以及构造器;