一.对象与类
1.什么是面向对象
DEF:基于对象编程,就是把要处理的数据交给对象,让对象来处理
2:类与对象的关系
类:类是具有相同的状态和相同的行为一组对象的集合(例如猫,狗),是一种抽象概念
对象:对象是将类实例化,比如波斯猫,邻居老王,法外狂徒张三等等
两者的关系:
类是多个对象进行综合抽象的结果,是实体对象概念的模型;而对象是一个类的实例.
二.对象和类的创建
1.定义类
public class Student { // 类的字段声明 // 类的方法声明 }
语法解析 (1) 访问修饰符如public、private等是可选的,其具体含义在后面讲解。 (2) class是声明类的关键字。 按照命名规范,应使用帕斯卡命名法,因此类名首字母大写
方法首字母不大写,但是要用小驼峰命名法(第一个单词后首字母大写)
2.类的字段
类的内部包含字段和方法。对象所拥有的特征在类中表示时称为类的字段,字段使用 变量表示。 定义字段的语法格式如下:
[访问修饰符] 数据类型 字段名;
语法解析 (1) 访问修饰符是可选的。 (2) 除了访问修饰符外,其他部分与定义变量相同
3.创建对象
类是一类事物的集合和抽象,代表着这类事物共有的字段和行为。一个对象称为类的 一个实例,是类一次实例化的结果。例如“宋江”是一个“人”类的具体对象。 类的对象可以调用类中的成员,如调用类的字段、调用类的方法等。 创建对象的语法格式如下:
Student stu = new Student();
语法解析: (1) new是关键字,称为实例化。 (2) 左边的类名为对象的数据类型。 (3) 右边的类名( )称为类的构造方法。 [访问修饰符] 数据类型 字段名;
4.使用对象
在Java中,要引用对象的字段和方法,需要使用成员运算符“.”。 使用对象的语法格式如下:
对象名.属性 // 引用对象的字段 对象名.方法名() // 引用对象的方法
5.对象在内存的原理
Student s1 = new Student();
以这句为例
-
Student s1 表示的是在栈内存中,创建了一个Student类型的变量,变量名为s1
-
而 new Student() 会在堆内存中创建一个对象,而对象中包含学生的属性名和属性值
同时系统会为这个Student对象分配一个地址值 0x4f3f5b24
-
接着把对象的地址赋值给栈内存中的变量s1,通过s1记录的地址就可以找到这个对象
-
当执行 s1.name=“播妞” 时,其实就是通过s1找到对象的地址,再通过对象找到对象的name属性,再给对象的name属性赋值为 播妞 ;
搞 明 白 Student s1 = new Student(); 的 原 理 之 后 , Student s2 = new Student(); 原理完全一样,只是在堆内存中重新创建了一个对象,又有一个新的地 址。 s2.name 是访问另一个对象的属性。],两者地址不同
三.关于static修饰符
1.方法中static的作用
在Java中,方法的定义中是否包含 static
关键字会导致方法的行为和用法产生重要的区别。以下是方法定义中是否包含 static
的主要区别:
1.方法中static的作用
-
静态方法(带有
static
关键字):-
静态方法属于类本身,而不是类的实例。这意味着你可以直接通过类名调用静态方法,而不需要先创建类的实例。
-
静态方法无法直接访问实例变量,因为它不属于任何特定的实例。它只能访问静态变量或者其他静态方法。
-
静态方法不能被覆盖(override),因为它是与类相关的,而不是实例相关的。子类可以定义与父类相同签名的静态方法,但不会产生方法覆盖的效果。
-
通常在实现工具方法、单例模式、获取类级别信息等方面使用静态方法。
-
-
实例方法(不带
static
关键字):-
实例方法是依附于类的实例的,因此在调用实例方法之前必须先创建类的实例。
-
实例方法可以访问实例变量和静态变量,以及其他实例方法和静态方法。
-
实例方法可以被覆盖,子类可以通过覆盖父类的方法来改变方法的实现。
-
通常在与实例状态相关的操作、封装、多态等方面使用实例方法
-
2.类中static的作用
1. 非静态成员(实例成员):
-
属性(实例变量):每个类的实例(对象)都会拥有自己的属性副本,它们的值可以不同。这意味着每个对象的属性是独立的。
-
方法(实例方法):实例方法属于类的实例,可以访问实例变量,也可以调用其他实例方法。它们可以访问对象的状态,并且可以被子类继承和覆盖(override)。
2. 静态成员:
-
静态属性(静态变量):静态属性属于类本身,而不是类的实例。所有的实例将共享同一个静态属性,它们的值是相同的。静态属性通常用于在类的所有实例之间共享数据。
-
静态方法:静态方法属于类本身,而不是类的实例。它们不能直接访问实例变量,只能访问静态变量或者其他静态方法。静态方法通常用于执行与类而非特定实例相关的操作。
3.调用两种成员的区别
调用非静态成员(实例成员):(通过对象调用)
-
属性(实例变量):非静态属性属于对象的实例,因此在调用时需要通过对象引用来访问。每个对象都有自己的属性副本。
javaCopy codeMyClass obj = new MyClass(); int value = obj.instanceVariable; // 访问实例属性
-
方法(实例方法):非静态方法也属于对象的实例,所以同样需要通过对象引用来调用。
javaCopy codeMyClass obj = new MyClass(); obj.instanceMethod(); // 调用实例方法
调用静态成员:(通常类名访问)
-
静态属性(静态变量):静态属性属于类本身,可以通过类名直接访问,也可以通过对象引用访问。然而,建议通过类名来访问,以明确表明这是一个类级别的属性。
javaCopy codeint value1 = MyClass.staticVariable; // 通过类名访问静态属性 MyClass obj = new MyClass(); int value2 = obj.staticVariable; // 通过对象引用访问静态属性(不推荐)
-
静态方法:静态方法属于类本身,可以直接通过类名来调用,也可以通过对象引用来调用。然而,与静态属性一样,建议通过类名来调用静态方法,以明确表明这是一个类级别的方法。
javaCopy codeMyClass.staticMethod(); // 直接通过类名调用静态方法 MyClass obj = new MyClass(); obj.staticMethod(); // 通过对象引用调用静态方法(不推荐)
四.构造方法
1.无参构造
-
没有参数:无参构造函数不接受任何参数。
-
默认提供:如果你在类中没有显式定义任何构造函数,Java会自动为你提供一个无参构造函数。如果你定义了其他任何构造函数,包括有参构造函数,Java就不会再提供默认的无参构造函数。
-
用途:无参构造函数通常用于创建对象的基本实例,可以在对象创建后使用其他方法或属性进行初始化。
示例:
javaCopy codepublic class MyClass { // 无参构造函数(默认提供) public MyClass() { // 构造函数逻辑 } }
2.有参构造
-
接受参数:有参构造函数接受一定数量的参数,用于初始化对象的属性。参数数量和类型取决于你定义的构造函数。
-
需要显式定义:如果你希望自定义参数的初始化过程,就需要显式地定义有参构造函数。
-
用途:有参构造函数常用于在对象创建时提供初始值,从而避免创建对象后还需要调用额外的方法来进行初始化。
示例:
javaCopy codepublic class MyClass { private int value; // 有参构造函数 public MyClass(int initialValue) { value = initialValue; } }
区别
无参构造函数不接受任何参数,用于提供对象的基本实例。
有参构造函数接受参数,用于提供更多的初始化选项和数据传递。
无参构造函数在没有显式定义其他构造函数时会被默认提供。
有参构造函数需要显式定义,可以根据需要定义多个,以适应不同的初始化情况。
当构造多个方法后,会自动屏蔽掉默认构造方法
五.java中初始化中一些相关顺序
1.静态成员初始化:
-
静态变量初始化:静态变量初始化会在类加载时进行,它们只会初始化一次,并且在类的所有实例之间共享。
-
静态初始化块:静态初始化块是用
static
关键字声明的代码块,会在类加载时执行,用于进行静态成员的初始化或其他类级别的操作。
2.实例变量初始化:
-
实例变量初始化:实例变量初始化会在对象创建时进行,它们的初始化是在构造方法调用之前完成的。
-
实例初始化块:实例初始化块是用花括号括起来的代码块,会在构造方法调用之前执行。它用于进行实例变量的初始化或其他与对象实例相关的操作。
3.构造方法调用:
-
构造方法:构造方法是用于初始化对象的特殊方法。它们可以带有参数,根据调用的构造方法不同,可以实现不同的初始化逻辑。
其中实例初始化指:
在构造函数之后,会执行实例初始化的代码块。实例初始化用于在对象创建时执行额外的初始化操作,或者对实例变量进行赋值,因此根据不同程序中每次构造函数时会用例初始化
4.例题
public class Homework { { printA(); //第二步 输出0 a = 5;//第三步a=5 } int a = 1; //a=0 第一步 //a=1第三步 { printA();//第四步 输出 1 } public Homework(int a){ printA();//第五步输出1 this.a = a; //6赋值 printA(); //输出6 } public void printA(){ System.out.println(a); } public static void main(String[] args) { new Homework(6); } }
执行顺序如上
执行结果:0 1 1 6