类和对象
类和对象
面向对象与面向方法
-
面向对象:什么是面向对象
面向对象(Object-oriented)是一种程序设计的方法和编程范式,它以对象作为程序的基本单位,通过封装、继承、多态等概念来组织和实现程序逻辑。面向对象的编程思想强调将问题分解为对象的集合,每个对象具有自己的状态(属性)和行为(方法),并通过相互之间的消息传递来实现协助和交互。 -
面向方法
类和对象的概念
什么是类
-
类(Class)是用来对一个实体(对象)进行描述的,主要包括实体(对象)的属性和行为的描述。在Java语言中,类是面向对象编程的基本组织单位,它是对象的模版或者蓝图,描述了对象的属性和行为。
-
属性(Fields):类可以定义成员变量,也称为属性或字段。属性表示了对象的状态或特征,用于存储对象的数据。每个对象通过类的属性来描述自己的特定状态。
-
方法(Methods):类可以定义成员方法,也称为方法或函数。方法定义了对象的行为或操作,用于执行特定的功能。方法可以访问和操作类的属性,以及与其他对象进行交互。
-
对象实例化(Instantiation):类本身只是一个模板,需要通过实例化(Instantiation)来创建对象。通过关键字 “new” 加上类名,可以在内存中创建一个对象的实例。
-
构造方法(Constructor):构造方法是一种特殊的方法,在对象实例化时被调用,用于初始化对象的状态。构造方法与类同名,没有返回类型,并可以接受参数。
-
封装性(Encapsulation):类通过封装将数据和方法组合在一起,将对象的内部细节隐藏起来,只暴露出必要的接口供外部访问。通过访问修饰符(如private、public等),可以控制对类的属性和方法的访问权限。
-
继承(Inheritance):类可以通过继承(Inheritance)机制创建子类,子类继承了父类的属性和方法,并可以添加自己的特定功能。继承实现了代码的重用,提高了代码的可扩展性和可重用性。
-
抽象类(Abstract Class):抽象类是一种不能被实例化的类,它提供了一种用于派生子类的模板。抽象类可以包含抽象方法和具体方法,子类必须实现抽象方法才能被实例化。
-
接口(Interface):接口是一种纯抽象的类,它定义了一组方法的规范,但没有实际的实现。类可以实现一个或多个接口,实现接口的类必须实现接口中定义的所有方法。
-
定义一个名为Person的类
public class Person {
// 成员变量
public String name;
public int age;
// 构造方法
public Person(String name, int age) {
this.name = name;
this.age = age;
}// 成员方法
public void sayHello() {
System.out.println("Hello, my name is " + name + " and I am " + age + " years old.");
}// 入口方法
public static void main(String[] args) {
// 创建一个Person对象实例
Person person = new Person("John", 25);// 调用对象的成员方法 person.sayHello();}
}
什么是对象
- 对象说白了也是一种数据结构(对数据的管理模式),将数据和数据的行为放到了一起。
- 在内存上,对象就是一个内存块,存放了相关的数据集合!
- 对象的本质就一种数据的组织方式!
- 总结
1.对象是具体的事物;类是对对象的抽象;
2.类可以看成一类对象的模板,对象可以看成该类的一个具体实例。
3.类是用于描述同一类型的对象的一个抽象概念,类中定义了这一类对象所应具有的共同的属性、方法。
成员变量
静态变量(类变量): 独立于方法之外的变量,用 static 修饰。
-
类变量在类里定义,声明变量时,在变量类型前面加上 static 即可,但必须在方法之外。
-
类变量有默认值,数值型变量默认值是 0(或者0.0),布尔型默认值是 false,引用类型默认值是 null。
-
类变量可以直接在该类的方法里使用。
public class CSDNTest {
//定义类变量
public static double i = 2000;public static void main(String[] args) {
//直接使用类变量
System.out.println(i);//2000
}
}
实例变量: 独立于方法之外的变量,不过没有 static 修饰。
-
实例变量声明在一个类中,但在方法、构造方法和语句块之外 。
-
实例变量具有默认值。数值型变量的默认值是0(或者0.0),布尔型变量的默认值是false,引用类型变量的默认值是null。
-
实例变量从属于对象-
public class CSDNTest { //实例变量 String name;int age;
public static void main(String[] args) { //变量类型 变量名 = new 类名(); CSDNTest test = new CSDNTest(); System.out.println(test.age);//0 System.out.println(test.name);//null //因为 age 和 name 都没有初始化,直接输出了默认值。}
}
成员方法
在Java中,成员方法(Member Method)是指那些属于类(Class)或接口(Interface)的一部分,可以被类的对象(Object)访问和调用的函数或过程。它们分为静态(Static)方法和实例(Instance)方法:
静态方法(Static Method):这类方法不需要创建对象就可以直接通过类名调用,通常用于提供一些全局操作或工具函数,因为它们与特定对象无关。
public class MyClass {
public static void staticMethod() {
// 方法体...
}
}
实例方法(Instance Method):也称为非静态方法,每个对象都有其独立副本。通过对象调用这些方法,可以直接操作该对象的状态(属性)。实例方法需要先创建对象才能调用。
public class MyClass {
public void instanceMethod() {
// 方法体...
}
}
MyClass obj = new MyClass();
obj.instanceMethod();
对象的实例化
构造器
无参构造器
-
定义:
无参构造器(No-Argument Constructor)是一个不接受任何参数的构造方法。在Java等面向对象的编程语言中,如果类中没有显式定义任何构造器,编译器会自动为该类生成一个默认的无参构造器。但一旦类中定义了至少一个构造器(无论是有参还是无参),编译器就不会再自动生成默认的无参构造器。 -
作用:
初始化对象时,为对象分配内存空间后,通过无参构造器可以初始化对象的默认状态。
允许对象在创建时不需要任何外部输入就能被实例化。 -
使用场景:
当一个类不需要在创建对象时接收任何参数来初始化其状态时,可以使用无参构造器。
在使用反射机制创建对象时,通常需要无参构造器。
示例:
public class Person {
// 显式定义的无参构造器
public Person() {
System.out.println("Person对象被创建了,使用无参构造器");
}
}
// 使用
Person person = new Person(); // 调用无参构造器
有参构造器
-
定义:
有参构造器(Parameterized Constructor)是接收一个或多个参数的构造方法。与无参构造器不同,有参构造器允许在创建对象时传入初始值,用于初始化对象的特定属性。 -
作用:
在对象创建时,根据传入的参数来初始化对象的属性。
提供了对象初始化的灵活性。 -
使用场景:
当需要在对象创建时立即根据外部输入设置其状态时,使用有参构造器。
-
示例:
public class Person {
private String name;
private int age;
// 有参构造器
public Person(String name, int age) {
this.name = name;
this.age = age;
System.out.println("Person对象被创建了,姓名:" + name + ",年龄:" + age);
}
}
// 使用
Person person = new Person("Alice", 30); // 调用有参构造器
构造器重载
-
定义:
构造器重载(Constructor Overloading)是指在同一个类中定义多个构造器,这些构造器的名称相同(即都是类的名称),但它们的参数列表不同(参数的数量、类型或顺序至少有一项不同)。 -
作用:
提供了创建对象的多种方式,每种方式都可以根据传入的参数不同来初始化对象的不同属性。
增加了类的灵活性和可用性。 -
使用场景:
当一个类需要根据不同的输入数据来初始化对象时,可以使用构造器重载来提供多种初始化方式。
示例:
public class Person {
private String name;
private int age;
// 无参构造器
public Person() {
this.name = "Unknown";
this.age = 0;
}
// 有参构造器1,仅姓名
public Person(String name) {
this.name = name;
this.age = 0; // 假设默认年龄为0
}
// 有参构造器2,姓名和年龄
public Person(String name, int age) {
this.name = name;
this.age = age;
}
}
// 使用
Person person1 = new Person(); // 使用无参构造器
Person person2 = new Person("Bob"); // 使用有参构造器1
Person person3 = new Person("Charlie", 25); // 使用有参构造器2
对象的使用
创建对象
- 创建对象是使用对象的第一步。这通常是通过调用类的构造器(Constructor)来完成的。构造器是一个特殊的方法,用于在创建对象时初始化其状态。
ClassName objectName = new ClassName(arguments);
这里,ClassName 是类的名称,objectName 是你创建的对象的变量名,arguments 是传递给构造器的参数(如果有的话)。
- 访问对象的属性
对象的属性(也称为字段或变量)封装了对象的状态信息。通常,对象的属性应该是私有的(private),以防止外部代码直接访问和修改它们,从而保持对象的封装性。然而,可以通过在类中提供公共的getter和setter方法来访问和修改私有属性。
// 假设有一个名为Person的类,该类有一个私有属性name和一个公共的getter方法getName()
Person person = new Person("Alice");
String name = person.getName(); // 使用getter方法访问私有属性
- 调用对象的方法
对象的方法定义了对象可以执行的操作。调用对象的方法通常是通过点操作符(.)完成的,该操作符用于指定要调用哪个对象的方法。
// 假设Person类有一个名为greet的方法
person.greet(); // 调用person对象的greet方法
- 对象之间的交互
在复杂的系统中,对象之间经常需要交互。这可以通过传递对象作为参数、返回对象作为方法的结果,或者通过对象之间的直接通信(如调用对方的方法)来实现。
// 假设有两个类,Employee和Department
Employee emp = new Employee("John Doe");
Department dept = new Department("Engineering");
// 将员工分配给部门
dept.assignEmployee(emp); // 假设Department类有一个assignEmployee方法
// 假设Employee类有一个方法可以打印出其所属的部门
emp.printDepartment(); // 这将依赖于Employee类中是否有保存Department引用的逻辑
对象的销毁
- 虽然Java等自动内存管理语言中的对象销毁是由垃圾收集器自动完成的,但了解何时对象可能变得不再可达(即没有活动引用指向它)是很重要的。当对象不再可达时,垃圾收集器将在未来的某个时间点回收它所占用的内存。
GC垃圾回收器的定义与作用
- GC垃圾回收器是负责执行垃圾回收任务的组件,它的主要作用是自动检测并回收程序中不再被使用的内存对象,从而避免内存泄漏和内存溢出等问题,保证程序的稳定运行。
GC垃圾回收的常见算法
GC垃圾回收器通过不同的算法来检测垃圾对象,并回收它们所占用的内存空间。常见的算法包括:
- 引用计数算法:维护每个对象的引用计数,当某个对象的引用计数为0时,即可视为垃圾并回收。这种算法实现简单,但无法处理循环引用的情况。
- 标记-清除算法:从根对象(如虚拟机栈中的对象引用、静态属性引用的对象等)出发,标记所有可以访问到的对象,然后清除未被标记的对象。这种方法可以处理循环引用,但会产生内存碎片。
- 复制算法:将内存空间分为两部分,每次只使用其中一部分。当这部分内存使用完后,将存活的对象复制到另一部分空间中,然后清除原空间的所有对象。这种方法解决了内存碎片问题,但会牺牲一部分内存空间。
- 标记-整理算法:与标记-清除算法类似,但在清除阶段不是直接回收未被标记的对象,而是让所有存活的对象都向一端移动,然后直接清理掉边界线以外的内存。这种方法同样解决了内存碎片问题,且不需要额外的内存空间。
匿名对象
一、匿名对象的定义
匿名对象是指在创建对象时,只有创建对象的语句,却没有把对象地址值赋值给某个变量。也就是说,这个对象被创建出来之后,没有通过变量名来引用它,因此被称为匿名对象。
二、匿名对象的特性
没有变量名:匿名对象在创建时,没有与之关联的变量名,因此无法直接通过变量名来引用它。
只能使用一次:由于匿名对象没有变量名,因此一旦创建并使用了它的某个方法或属性后,就无法再次通过该对象进行其他操作。如果需要再次使用对象,必须重新创建。
生命周期短暂:匿名对象的生命周期通常非常短暂,仅在其被创建的语句中有效。一旦该语句执行完毕,匿名对象就可能被垃圾回收器回收。
三、匿名对象的使用场景
当只需要调用一次对象的方法时:如果某个对象只需要被创建一次,并且只调用其一个方法,那么使用匿名对象可以简化代码,避免不必要的变量声明和赋值。
作为方法的参数:匿名对象可以作为方法的参数传递,特别是当方法的参数类型为某个类的实例时,如果不需要在方法外部引用该对象,可以使用匿名对象作为参数。
作为方法的返回值:在某些情况下,方法需要返回一个对象的实例,但如果这个对象只需要在返回后被使用一次,那么可以在方法内部创建并返回一个匿名对象。
四、示例代码
java
public class Test {
public static void main(String[] args) {
// 匿名对象作为方法的参数
printName(new Person("Alice"));
// 匿名对象作为方法的返回值
Person person = getPerson();
if (person != null) {
person.show();
}
}
public static void printName(Person p) {
if (p != null) {
System.out.println(p.getName());
}
}
public static Person getPerson() {
// 返回一个匿名对象
return new Person("Bob") {
@Override
public void show() {
System.out.println("This is an anonymous Person object.");
}
};
}
static class Person {
private String name;
public Person(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void show() {
// 默认实现(如果子类不覆盖)
}
}
}

浙公网安备 33010602011771号