面向对象编程(Object-Oriented Programming,简称OOP)和面向过程编程(Procedure-Oriented Programming)是两种不同的编程范式,它们在设计和实现软件时采用了不同的方法和哲学。

一、面向对象编程

  1. 核心概念:面向对象编程的核心是"对象",对象可以包含数据(属性)和代码(方法)。万物皆对象。

  2. 封装:将数据和操作数据的方法组合在一起,隐藏内部实现细节。

  3. 继承:允许新创建的类(子类)继承现有类(父类)的属性和方法。

  4. 多态:允许不同类的对象对同一消息做出响应,但具体的行为会根据对象的实际类型而有所不同。

  5. 应用:面向对象编程适用于大型、复杂的系统,可以提高代码的复用性和可维护性。

    优点:可维护性,可复用性,可扩展性,灵活性好。

二、面向过程编程

  1. 核心概念:面向过程编程侧重于将问题分解成一系列的过程或函数。
  2. 过程:每个过程执行特定的任务,并且可以调用其他过程。
  3. 数据和函数分离:数据和处理数据的函数是分开的,函数操作数据但不包含数据。
  4. 优点:简单、直观,适合小型或逻辑简单的程序。
  5. 缺点:难以维护,无法复用,难以扩展,灵活性差。

三、对比

  • 设计哲学:面向对象强调的是数据和功能的结合,面向过程则强调的是功能的分解。
  • 代码组织:面向对象通常以类和对象的形式组织代码,面向过程则以函数和过程的形式组织。
  • 可维护性:面向对象由于其封装、继承和多态的特性,通常更容易维护和扩展。
  • 适用场景:面向对象适合于需要高度模块化和可复用性的复杂系统,而面向过程适合于逻辑简单、规模较小的程序。

一、什么是类

类(Class)

  1. 定义:类是现实世界中某些具有共同属性(数据)和方法(行为)的对象的抽象和模板。类是封装对象的属性和行为的载体。
  2. 属性:类中的属性代表了对象的状态信息,通常是变量。
  3. 方法:类中的方法定义了对象的行为,通常是函数。
  4. 封装:类通过将数据和操作数据的方法封装在一起,保护了数据不被外部直接访问,只能通过类提供的方法进行操作。
  5. 创建:通过类可以创建多个对象实例,每个实例拥有自己的状态,但共享相同的行为定义

二、什么是对象

  1. 实例:对象是类的实例化,每个对象都是一个独立的实体,拥有自己的属性值。
  2. 状态:对象的状态由其属性值决定,不同的对象可以有不同的状态。
  3. 行为:对象的行为由类中定义的方法决定,所有对象实例共享相同的方法。
  4. 交互:对象之间可以通过消息传递进行交互,一个对象可以请求另一个对象执行其方法。
  5. 作用:对象是程序中的基本单位,用于存储数据和执行操作。

类与对象的关系

  • 模板与实例:类是创建对象的模板,对象是类的实例。就像模具和铸造出来的产品一样。
  • 属性与状态:类的属性定义了对象可能拥有的状态,而对象的属性值则代表了其当前状态。
  • 方法与行为:类的方法定义了对象的行为,对象通过调用这些方法来执行操作。
  • 多态性:对象可以通过继承和接口实现多态性,即不同的对象可以对相同的消息做出响应,但具体的行为会根据对象的实际类型而有所不同。

三、成员变量

属性(成员变量)=访问修饰符+数据类型+变量名

Java中,对象的属性也称为成员变量,成员变量可以是任意类型,成员变量的作用域是整个类。

public calss Book{    //定义一个书类
	private String name;  //定义String类型的成员变量
	public String getName(){  //成员变量name的get方法
        return name;
    } 	
   
   public void setName(String name){   //成员变量name的set方法
       this.name = name;   //将参数值赋给成员变量name
   }
}

上面创建的是一个Book类,在类中设置了一个name属性,并编写了该属性的Getter/Setter方法。

在Java语言中定义类需要使用class关键字,Book是类的名称,在Book类中定义了一个成员变量,成员变量的类型为String类型。成员变量其实就是一个普通的变量,可以为它设置初始值,也可以不设置初始值,如果不设置初始值,那么会有默认的初始值。

四、成员方法

在Java中,使用成员方法对应于类对象的行为,以上面的Book类为例,它包含了getName()和setName()两个方法,这两个成员方法分别为获取图书名称和设置图书名称的方法。

定义成员方法的语法格式如下:

权限修饰符  返回值类型  方法名(参数类型  参数名){
	……    //方法体
	return 返回值;
}

一个成员方法可以有参数,这个参数可以是对象,也可以是基本数据类型的变量,同时成员方法有返回值和不返回任何值的选择,如果方法需要返回值,可以使用return关键字来返回值,使用这个关键字,方法执行到这句语句的时候,方法将被中止。(如果想要使成员方法无返回值,可以使用void关键字表示)。

成员方法的返回值可以是计算结果,也可以是其它想要的数值和对象,返回值的类型要与方法返回值类型一致。

在成员方法中可以调用其他成员方法和类成员变量,在成员方法中也可以定义一个变量,但是方法中定义的变量为局部变量。

成员方法和成员变量统称为类成员。

五、对象实例化(构造器)

对象实例化是一个过程,它创建了类的一个具体实例,即对象。不同的编程语言有不同的语法来实现对象的实例化。构造器是类中用于实例化Java对象的一个特殊方法,该方法要求方法名必须与类名相同

1.默认构造器(无参)

当一个类没有构造器,就默认为无参构造器。当有构造器时,无参构造器需手写。

public 类名(){}

默认构造器不接收任何参数,会调用父类的无参构造器(如果存在的话),然后初始化类的对象。

public class MyClass {
    private String name;

    // 没有显式定义构造器,编译器将提供一个无参构造器
}

// 实例化对象,使用默认的无参构造器
MyClass myObject = new MyClass();

MyClass有一个私有的name属性,但没有定义任何构造器。当你创建MyClass的实例时,使用的是默认的无参构造器。
2.有参构造器

有参构造器(Parameterized Constructor)是一种接收初始化参数的构造方法。当你创建对象时,可以传递参数给这些构造器,以便在对象创建时就初始化对象的状态。

以下是一些关于有参构造器的关键点:

  1. 定义:有参构造器的方法名必须与类名完全相同,并且不返回任何值(不包括void)。
  2. 参数:构造器可以有一个或多个参数,用于接收初始化数据。
  3. 作用:主要用于在创建对象时设置对象的初始状态。
  4. 调用:在创建对象时,必须提供与构造器参数匹配的参数值。

下面是一个Java类使用有参构造器的例子:

public class Person {
    private String name;
    private int age;

    // 有参构造器,接收两个参数:姓名和年龄
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 其他方法,例如获取姓名和年龄
    public String getName() {
        return name;
    }

    public int getAge() {
        return age;
    }
}

// 使用有参构造器实例化对象
Person person = new Person("Alice", 30);

包含无参构造器和有参构造器:

public class Person {
    private String name;
    private int age;

    // 无参构造器
    public Person() {
        this("Unknown", 0); // 调用有参构造器,设置默认值
    }

    // 有参构造器,接收两个参数
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }
}

// 使用无参构造器实例化对象,实际上会调用有参构造器
Person personDefault = new Person();

在这个例子中,无参构造器通过this("Unknown", 0);调用了有参构造器,从而实现了构造器之间的调用。这是一种常见的模式,用于为类的不同构造器提供一致的初始化逻辑。

3.构造器重载

构造器重载(Constructor Overloading)是Java中多态的一种表现,允许一个类拥有多个同名的构造器,只要它们的参数列表不同即可。这使得类能够提供多种方式来创建对象,每种方式都可以接受不同数量或类型的参数。

构造器重载的要点:

  1. 方法名相同:所有重载的构造器必须具有相同的方法名,即类名。
  2. 参数列表不同:构造器的参数数量或类型(或两者)必须不同。
  3. 返回类型:构造器没有返回类型,即使是void也不行。
  4. 访问修饰符:可以有不同的访问修饰符,但这不影响重载。
public class Car {
    private String model;
    private String color;
    private int year;

    // 无参构造器
    public Car() {
        this("Unknown", "Black", 0); // 默认构造器,调用有参构造器
    }

    // 有参构造器1:接收三个参数
    public Car(String model, String color, int year) {
        this.model = model;
        this.color = color;
        this.year = year;
    }

    // 有参构造器2:接收两个参数
    public Car(String model, int year) {
        this(model, "Black", year); // 调用另一个有参构造器
    }

    // 有参构造器3:接收一个参数
    public Car(String model) {
        this(model, "Black", 0); // 调用另一个有参构造器
    }

    // 其他方法...
}

// 使用不同的构造器实例化对象
Car car1 = new Car(); // 使用无参构造器
Car car2 = new Car("Tesla", "Red", 2021); // 使用有参构造器1
Car car3 = new Car("Toyota", 2020); // 使用有参构造器2
Car car4 = new Car("Honda"); // 使用有参构造器3

六、对象的使用

在面向对象编程(OOP)中,对象的使用通常涉及以下几个步骤:

  1. 定义类:首先,你需要定义一个类(Class),它是一个蓝图,描述了具有相同属性和方法的对象的结构。
  2. 实例化对象:使用类来创建一个或多个对象实例。这通常通过调用类的构造器完成。
  3. 访问属性:对象的属性(也称为字段或成员变量)可以通过点(.)操作符来访问和修改。
  4. 调用方法:对象的方法(也称为成员函数)可以通过点操作符调用,以执行某些操作或返回某些值。
  5. 修改对象状态:通过设置对象的属性,可以改变对象的状态。
  6. 实现接口或继承:对象可能实现了特定的接口或继承自其他类,这为它们提供了额外的行为或属性。
  7. 销毁对象:在某些语言中,如Java,对象会在不再被引用时由垃圾收集器自动销毁。在其他语言中,如C++,可能需要手动管理内存和对象的销毁。
// 定义一个类
class Person {
    private String name;
    private int age;

    // 构造器
    public Person(String name, int age) {
        this.name = name;
        this.age = age;
    }

    // 获取姓名的方法
    public String getName() {
        return name;
    }

    // 设置姓名的方法
    public void setName(String name) {
        this.name = name;
    }

    // 获取年龄的方法
    public int getAge() {
        return age;
    }

    // 描述个人信息的方法
    public void describe() {
        System.out.println("Name: " + name + ", Age: " + age);
    }
}

// 使用类创建对象
public class Main {
    public static void main(String[] args) {
        // 实例化Person类的对象
        Person person1 = new Person("Alice", 30);

        // 访问和修改属性
        person1.setName("Bob");
        person1.setAge(25);

        // 调用方法
        person1.describe(); // 输出: Name: Bob, Age: 25

        // 创建另一个对象
        Person person2 = new Person("Charlie", 40);
        person2.describe(); // 输出: Name: Charlie, Age: 40
    }
}

七、对象的销毁(GC垃圾回收)

在Java中,对象的销毁是由垃圾收集器(Garbage Collector, GC)自动管理的。当一个对象没有任何引用指向它时,它就变得“无用”,GC会在某个时间点回收它所占用的内存。 System.GC()

  • 垃圾收集触发条件:当对象没有被任何变量、对象或类引用时。
  • 垃圾收集过程:GC周期性地运行,检查对象的引用状态,并回收那些没有被引用的对象。
  • GC可回收new的对象,系统资源对象不能回收
public class Main {
    public static void main(String[] args) {
        Person person = new Person("Alice", 30);
        // 当person变量离开作用域或被设置为null时,对象可能被GC回收
        person = null; // 显式地断开引用,加快对象的回收
    }
}

八、匿名对象

匿名对象:没有名字的对象。只用一次。
格式如下:

new Person().showMessage();

 这种对象通常用于临时使用,不需要命名的情况。不同的编程语言对匿名对象的支持程度不同。

在Java中,匿名对象通常用于创建一次性使用的对象,或者作为参数传递给方法。例如,创建一个实现了Runnable接口的匿名对象,并将其作为线程启动:

在Java中,匿名对象通常用于创建一次性使用的对象,或者作为参数传递给方法。例如,创建一个实现了Runnable接口的匿名对象,并将其作为线程启动:
new Thread(new Runnable() {
    @Override
    public void run() {
        System.out.println("Hello from an anonymous Runnable!");
    }
}).start();

实例化对象方式:

new 对象

Object clone
image-20240801153912718

最高设计原则:高内聚低耦合。

  1. 继承(Inheritance):父类,子类
    • 继承是一种"是一个"(is-a)的关系。例如,如果有一个Animal类,可以有一个Dog类继承自它,因为狗是一种动物。
  2. 实现(Implementation):订票接口,网上订票类
    • 实现通常指的是一个类实现了一个接口。接口定义了一组方法,类必须实现这些方法,但接口本身不提供实现。
  3. 关联(Association):广泛普遍。有关系。双向,单项。学生类,老师类。消费者,店家。
    • 关联是一种"有"(has-a)的关系。例如,一个Car类可能有一个Engine类作为其属性,表示汽车有引擎。

    image-20240803091052815

  4. 聚合(Aggregation):整体和局部的关系,学生类,班级类
    • 聚合是一种特殊的关联,表示整体与部分的关系,但部分可以独立于整体存在。例如,一个University类可能聚合了多个Student类的对象。

    image-20240803092741135

  5. 组合(Composition):共存亡。如心脏,人
    • 组合也是整体与部分的关系,但与聚合不同,部分不能独立于整体存在。如果整体被销毁,部分也会被销毁。

    image-20240803092531110

  6. 依赖(Dependency):动物,水
    • 依赖是一种"使用"(uses-a)的关系。一个类可能在其方法中使用另一个类的对象,但不一定拥有它。