1、类、方法、对象的基本概念
类、方法、对象是面向对象编程的三个基本概念,其解释如下。
类(Class):
-
定义: 类是一种抽象数据类型,它是对现实世界中一类相似对象的抽象描述。类定义了对象的属性(成员变量)和行为(方法)。
-
特征: 类是一个模板或蓝图,描述了对象应该具有的特性和行为。
-
示例: 如果我们考虑一个类
Car
,它可能有属性如color
、model
,以及行为如start
、drive
。这个类描述了所有可能的汽车对象的共同特征和行为。
方法(Method):
-
定义: 方法是类中的函数或操作,它定义了对象的行为。方法是在类中执行特定任务的代码块。
-
特征: 方法用于对对象进行操作,改变对象的状态或返回某些信息。
-
示例: 在
Car
类中,可能有一个方法start()
用于启动汽车,以及一个方法drive()
用于驾驶汽车。这些方法定义了汽车对象的行为。
对象(Object):
-
定义: 对象是类的一个实例,它是内存中的一个实体,具有类定义的属性和行为。
-
特征: 对象是类的具体实现,每个对象都有自己的状态(通过成员变量表示)和行为(通过方法表示)。
-
示例: 如果有一个
Car
类,那么一辆具体的汽车(比如一辆红色的奔驰车)就是这个类的一个对象。这个对象具有特定的颜色、型号等属性,以及启动、驾驶等行为。
总结:
在一个类中包含许多属性和方法(类似于函数的作用),而如何让属性和方法建立联系,那就通过对象,我们可以通过new一个对象,这个实例化的对象包含了这些属性(也称为实例化字段),我们可以对这些属性初始化(也即赋值),然后利用实例化之后的对象去调用这些方法。三者关系如下图1所示:
2、实例字段、参数
实例字段(Instance Fields):
实例字段是类中声明的变量(和上文的属性是一个意思),通常用于表示对象的状态或属性。每个类的实例(对象)都有一组独立的实例字段,这些字段存储对象的特定属性。实例字段在类中声明,但在对象创建时分配内存。如下图2所示,value和name就是myclass这个类的实例字段
public class MyClass {
// 实例字段
private int value;
private String name;
// 构造方法
public MyClass(int value, String name) {
// 初始化实例字段
this.value = value;
this.name = name;
}
// 其他方法可以访问实例字段
public void displayInfo() {
System.out.println("Value: " + value + ", Name: " + name);
}
}
参数(Parameters):
参数是方法或构造方法中声明的变量,用于接收调用该方法时传递的值。参数提供了一种将数据传递给方法或构造方法的机制。在下图3中,value和name是构造方法的参数,而newvalue是方法setvalue的参数。
public class MyClass {
// 构造方法带有参数
public MyClass(int value, String name) {
// 在构造方法中使用参数
}
// 方法带有参数
public void setValue(int newValue) {
// 使用参数
}
}
区别与总结:
-
实例字段是类中声明的变量,用于存储对象的状态或属性。它们在类中声明,但在对象级别分配内存。
-
参数是方法或构造方法中声明的变量,用于接收调用该方法时传递的值。它们在方法或构造方法的调用时被传递,并用于在方法内部执行特定的逻辑。
在实际编程中,实例字段用于表示对象的属性,而参数用于传递调用方法时所需的数据。
3、方法和构造方法
方法(Method)
-
定义: 方法是在类中定义的一组执行特定任务的代码块。它可以用于执行某种操作、返回值或修改对象的状态。
-
特征:
-
方法包括方法名、返回类型、参数列表和方法体。
-
方法可以有返回值,也可以是
void
,表示没有返回值。 -
方法可以带有参数,也可以没有参数。
-
-
示例:如下图图4所示
public class MyClass {
// 方法示例
public int add(int a, int b) {
return a + b;
}
public void printMessage(String message) {
System.out.println(message);
}
}
在上述方法当中一个是对传入的参数求和一个是打印输出。至于什么时候可以调用该方法,将在后续部分给出。
构造方法(Constructor):
-
定义: 构造方法是一种特殊类型的方法,用于在创建对象时初始化对象的状态。它和类同名,没有返回类型。
-
特征:
-
构造方法在对象创建时自动调用。
-
构造方法可以有参数,也可以没有。
-
每个类至少有一个构造方法。如果没有显式定义构造方法,Java会提供一个默认的无参构造方法。
-
-
示例:
public class MyClass {
// 无参构造方法
public MyClass() {
// 构造方法体
}
// 带参构造方法
public MyClass(int initialValue) {
// 构造方法体,用传入的参数初始化对象的状态
}
}
在上面的例子中,MyClass
类有一个无参构造方法和一个带参构造方法。当创建 MyClass
对象时,会自动调用相应的构造方法来初始化对象的状态。
注意事项:
-
方法可以被多次调用,而构造方法只在对象创建时被调用一次。
-
构造方法和方法的语法区别在于构造方法没有返回类型,并且与类同名。
-
使用方法和构造方法有助于组织代码、提高代码的可读性和可维护性。构造方法主要用于初始化对象的状态,而方法用于定义对象的行为。
其实在方法中也会根据其不同的特点,将其分为各种方法。如普通方法、静态方法、抽象方法等。基于类的访问权限,可以将方法分为私有方法和公有方法,相应的字段也可以这样划分。在下文中主要介绍静态字段和静态方法,也会详细的介绍public和private生命的字段和方法到底有什么区别。
4、this和final关键字
this关键字
-
作用:
this
关键字用于引用当前对象,表示正在被执行的方法所属的对象。 -
使用场景:
-
避免参数名和实例字段名冲突:当方法的参数名与实例字段名相同时,使用
this
可以明确指示引用的是实例字段而不是参数。 -
在构造方法中调用其他构造方法:通过
this
可以在一个构造方法中调用同一类的其他构造方法。
-
-
例子:如下图6所示
public class MyClass {
private int value;
// 构造方法
public MyClass(int value) {
this.value = value; // 使用this引用实例字段
}
// 方法中避免参数名和字段名冲突
public void setValue(int value) {
this.value = value;
}
// 构造方法中调用其他构造方法
public MyClass() {
this(0); // 调用带参数的构造方法
}
}
在有参数构造时,this.value表示的是字段的value而value表示的是参数。在无参构造时this可以用来调用其他构造方法。
final关键字
-
作用:
final
用于声明常量,一旦被赋值后,其值不能被修改。 -
使用场景:
-
定义常量:当一个字段被声明为
final
时,其值在对象创建后不能再被修改,通常用于定义不可变的常量。
-
-
例子:如下图图7所示。
public class Constants {
public static final int MAX_VALUE = 100; // 常量,不能被修改
}
public class Example {
public static void main(String[] args) {
System.out.println(Constants.MAX_VALUE); // 访问常量
// Constants.MAX_VALUE = 200; // 编译错误,常量值不能被修改
}
}
总体而言:
this
用于引用当前对象,解决参数和实例字段名冲突的问题,以及在构造方法中调用其他构造方法。
final
用于声明常量,确保其值在初始化后不可被修改,提高代码的可读性和安全性。
5、静态字段与静态方法
在Java当中,如果一个类的某些字段是静态字段或者某些方法是静态方法的话(即用static关键字修饰的字段或者方法),可以直接通过类名直接访问相应的字段或者方法,而不需要创建类的实例进行调用。
静态字段(Static Fields):
-
定义: 静态字段是用
static
关键字修饰的类级别的字段,属于整个类而不是类的实例。每个类只有一个静态字段的副本,而不是每个实例都有一个。 -
特征:
-
静态字段通常用于表示类级别的信息,如常量或计数器。
-
可以通过类名直接访问,也可以通过对象访问,但推荐使用类名。
-
静态字段的值在类加载时初始化,并且在整个生命周期中保持不变。
-
-
示例:
public class MyClass {
// 静态字段示例
public static int staticField = 10;
// 其他非静态字段和方法...
}
静态方法(Static Methods):
-
定义: 静态方法是用
static
关键字修饰的方法,它属于类而不是类的实例。静态方法不能直接访问类的实例变量,因为它没有隐含的this
参数。 -
特征:
-
可以通过类名直接调用,而不需要创建类的实例。
-
静态方法通常用于执行与类相关而不是具体实例相关的操作,如工具方法或计算操作。
-
不能在静态方法中直接调用非静态字段或方法,但可以调用其他静态字段或方法。
-
-
示例:
public class MathUtils {
// 静态方法示例
public static int add(int a, int b) {
return a + b;
}
}
简单来说,对于普通的字段和方法,我们需要new一个对象,然后为相应的字段赋值,通过new的对象再去调用方法。
但是对于静态字段,我们可以直接使用,如上诉静态字段的实例,我们想用staticFieId时,直接MyClass.staticFieId即可。
对于静态方法,我们也不用去new一个对象,对于上诉例子,只需要int sum=MathUtils.add(10,11);即可调用方法。如果没有static这个
关键字,我们必须实例化一个对象(即new个对象)才能用add这个方法。
值得注意的是,根据Java核心技术里描述,我们也可以使用对象去调用静态方法,这是合法的,但是书中建议使用类名去调用静态方法,而不是对象。
6、内部类
内部类是定义在另一个类内部的类,下面将对常见的内部类进行介绍。
-
成员内部类(Member Inner Class): 成员内部类是定义在另一个类内部的普通类。它具有访问外部类的成员的权限。
public class OuterClass {
private int outerField;
public class InnerClass {
public void innerMethod() {
System.out.println("Accessing outer field: " + outerField);
}
}
}
在上诉例子当中,InnerClass是OuterClass的内部类,其可以直接访问外部类的成员变量
-
局部内部类(Local Inner Class): 局部内部类是定义在方法内部的类。它只在声明它的方法中可见。
public class OuterClass {
public void outerMethod() {
class LocalInnerClass {
public void innerMethod() {
System.out.println("Inside local inner class");
}
}
LocalInnerClass localInner = new LocalInnerClass();
localInner.innerMethod();
}
}
-
内部静态类(Static Nested Class):内部静态类是定义在另一个类内部并用
static
修饰的类。与成员内部类不同,它不依赖于外部类的实例,可以直接通过外部类的名字访问。
注意:内部静态类是最常见的内部类,静态内部类中使用static修饰该内部类,静态内部类不依赖于外部类的实例,其两者之间相对独立
静态内部类可以直接通过外部类名引用,而无需外部类创建实例,下面通过一个实例来说明,内部类加static和不加static的区别。
public class P25_AssignmentOperator {
public static class MyString {
private String data;
public MyString(String data) {
this.data = data;
}
public MyString assign(final MyString another) {
if (this == another || this.data.equals(another.data))
return this;
else {
this.data = another.data;
return this;
}
}
@Override
public String toString() {
return "MyString{" +
"data='" + data + '\'' +
'}';
}
}
public static void main(String[] args) {
MyString s1 = new MyString("a");
MyString s2 = new MyString("b");
MyString s3 = new MyString("c");
System.out.println(s1.assign(s2).assign(s3));
System.out.println("s1:" + s1);
// 如果将内部类的static静态变量去掉,可以按以下方式创建内部类对象
P25_AssignmentOperator p25AssignmentOperator = new P25_AssignmentOperator();
P25_AssignmentOperator.MyString myString = p25AssignmentOperator.new MyString("a");
}
}
上诉例子是剑指offer上面的一个面试题目。通过这个实例来帮助大家理解静态内部类与非静态内部类的区别
7、public 和 private
在Java中,经常会使用public和private来修饰字段和方法,下面本文就对这两个字段进行简单的介绍。
public
-
公有字段(public):
-
共有字段可以被类的外部访问。
-
其他类可以直接读取或修改公有字段的值。
-
public class MyClass {
public int publicField; // 这是一个公有字段
}
-
公有方法(public):
-
公有方法可以被类的外部访问。
-
其他类可以通过对象调用这些公有方法。
-
private
-
私有字段(private)
-
私有字段只能在声明它们的类内部访问。
-
其他类无法直接访问或修改私有字段的值。
-
-
私有方法(private)
-
私有方法只能在声明它的类内部访问。
-
它们对于类的外部是不可见的,这意味着其他类无法直接调用或访问这些私有方法。
-
-
私有类(private class)
-
私有类是使用 `private‘修饰符声明的类,只能在声明它的外部类中被访问。其他类无法直接访问私有类。
-
public class OuterClass {
private class PrivateClass {
// 私有类的成员和方法...
}
// 外部类的其他成员和方法...
}
在上述例子中,PrivateClass
是 OuterClass
的私有类,只能在 OuterClass
内部被访问。
这就是我认为类与对象,值得注意的点,后续将会更新继承、集合等知识。