面向对象编程(Object-Oriented Programming,简称OOP)的三大特征分别是:
封装(Encapsulation)、继承(Inheritance)和多态(Polymorphism)。下面我会分别解释这三个特征。
1、封装(Encapsulation):
概念:
封装是面向对象编程的核心思想之一。封装指的是将数据(属性)和操作数据的方法(函数)绑定在一起,作为一个独立的对象。在封装的过程中,对象将其内部的实现细节隐藏起来,只对外提供公共的访问方式(如公共的属性和方法)。这样做的好处是提高了代码的安全性、可维护性和可重用性。
实现方法:
实现封装在面向对象编程中,主要是为了确保数据的安全性和提高代码的可维护性。以下是实现封装的基本步骤:
- 将属性私有化:首先,你需要将类的属性(即数据成员)设置为私有(通常使用
private
关键字)。这样,类的外部就无法直接访问或修改这些属性,只能通过类提供的方法来间接操作它们。 - 提供set方法:然后,你需要为每个私有属性提供一个公有的
set
方法(有时也称为setter方法)。这个方法允许类的外部通过调用它来设置属性的值。在set
方法中,你可以添加一些验证逻辑,以确保设置的值是合法和有效的。 - 提供get方法:同样,你也需要为每个私有属性提供一个公有的
get
方法(有时也称为getter方法)。这个方法允许类的外部通过调用它来获取属性的值。由于get
方法只是返回属性的值,所以它通常不包含任何验证逻辑。
以下是一个简单的Java示例,展示了如何实现封装:
public class Person {
// 将属性私有化
private String name;
private int age;
// 提供set方法
public void setName(String name) {
if (name != null && !name.isEmpty()) {
this.name = name;
} else {
System.out.println("Invalid name!");
}
}
public void setAge(int age) {
if (age >= 0 && age <= 120) {
this.age = age;
} else {
System.out.println("Invalid age!");
}
}
// 提供get方法
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
在这个示例中,Person类的 name 和 age 被设置为私有,因此类的外部不能直接访问它们。相反,类的外部必须通过调用setName,setAge,getName和getAge这四个公有的方法来间接操作这些属性。这样,你就可以在set
方法中添加验证逻辑,以确保设置的值是合法和有效的。
有时构造器会越过set方法中的验证逻辑,为解决这一问题,我们可以将set方法与构造器相结合,也就是将set方法写在构造器中,这样构造器也需满足set中的逻辑判断才能执行其构造。
2、继承(Inheritance):
概念:
继承是面向对象编程中实现代码重用的一种机制。它允许我们定义一个类(称为父类或基类),然后创建另一个类(称为子类或派生类),子类可以继承父类的属性和方法。子类在继承父类的基础上,可以添加新的属性和方法,也可以重写父类的方法。继承提高了代码的复用性,使得代码更加简洁和易于管理。
注意事项:
1、创建子类对象时,会默认调用父类的无参构造器。
2、若父类未显式定义无参构造器,则需在子类构造器中使用super去指定调用父类中的某一构造函数,例:
public class Teacher extends Person{
public Teacher(String name, char sex, int age) {
super(name, sex, age);
}//使用super调用父类中的构造方法
}
3、super只能在构造器中使用,且只能放在第一行(使用this()调用当前类的另一个构造器时,也只能放在第一行,所以两者不能共存于同一构造器中)。
4、java中存在基类:Object类,所有类都是它的子类。
3、多态(Polymorphism):
概念:
多态是面向对象编程的一个重要特性,它允许我们使用父类类型的引用指向子类对象,并且调用子类的方法。在运行时,根据对象的实际类型来执行相应的方法。多态的实现依赖于方法的重写(Override)和方法的重载(Overload)。多态使得代码更加灵活和可扩展,提高了程序的可读性和可维护性。
注意事项:
1、两个对象/类必须存在继承关系。
2、向上转型:子类对象赋值给父类类型的变量;向下转型:父类类型变量赋值给子类类型的变量。
class Main go {
public static void main(String[] args) {
Animal animal = new Dog(); // 向上转型
Dog dog = (Dog) animal; // 向下转型,显式转换
}
}
3、无论如何转型,改变的都只是其编译类型,而运行类型在创建时就已确定,无法改变。
4、动态绑定机制:调用方法时,该方法会根据以运行类型(对象的内存地址)来运行;调用变量时,不存在动态绑定机制,哪里声明,哪里使用。
总结:
面向对象编程的三大特征封装、继承和多态共同构成了面向对象编程的核心思想。
封装隐藏了对象的内部实现细节,提高了代码的安全性和可维护性。
继承实现了代码的重用,使得代码更加简洁和易于管理。
多态提高了代码的灵活性和可扩展性,使得程序更加易于理解和维护。