了解 OOP 中的封装、继承、多态、抽象
顾名思义,面向对象编程或 OOP 是指在编程中使用对象的语言。面向对象编程旨在在编程中实现继承、隐藏、多态等现实世界的实体。 OOP 的主要目的是将数据和对它们进行操作的函数绑定在一起,这样代码的其他部分就不能访问这些数据,除了那个函数。在本文中,我们将通过一个示例了解 OOP 的所有概念。
假设我们有一个鸟类类,我们正在创建一个鸟类列表。让我们了解这个鸟创建中使用的 OOP 的概念。
继承:对于任何鸟类,都有一组预定义的属性,这些属性对所有鸟类都是通用的,并且有一组特定于特定鸟类的属性。因此,直观地说,我们可以说所有的鸟类都继承了翅膀、腿、眼睛等共同特征。因此,在面向对象的表示鸟类的方式中,我们首先声明一个鸟类类,它具有一组属性,这些属性是所有鸟类共有。通过这样做,我们可以避免在我们创建的每只鸟中声明这些共同属性。相反,我们可以简单地继承我们创建的所有鸟类中的鸟类类。以下是如何实现继承概念的示例。
// Java program to demonstrate
// the bird class
// Implementing the bird class
public class Bird {
// Few properties which
// define the bird
String color;
int legs;
// Few operations which the
// bird performs
public void eat()
{
System.out.println(
"This bird has eaten");
}
public void fly()
{
System.outp.println(
"This bird is flying");
}
}
在bird类实现之后,如果我们想创建一只鸽子,那么我们只需继承上面的Bird类即可。
// Java program to demonstrate the
// Inheritance
// Creating the Pigeon class which
// extends the bird class
public class Pigeon extends Bird {
// Overriding the fly method
// which makes this pigeon fly
public void fly()
{
System.out.println(
"Pigeon flys!!!!");
}
}
封装:现在,我们已经定义了鸟类的属性,鸟类的颜色、翅膀、腿等属性可以通过创建鸟类的对象来初始化。但是,如果我们仅仅能够通过对象的引用来改变鸟类的属性,那么属性就会丢失最初初始化它的信息。
例如,假设我们最初通过创建构造函数创建了一个灰色的鸽子,任何拥有鸽子对象实例的用户都可以通过简单地使用“this”关键字引用属性来将该颜色更改为红色或黑色。因此,为了避免这种情况,我们将属性包含在方法中。这些方法称为属性的getter 和setter。这个想法是简单地将属性的初始化和检索包含在方法中,而不是直接直接引用属性。这也带来了一个优势,因为 setter 让我们可以完全控制将值设置为属性,并帮助我们限制不必要的更改。例如,如果一只鸽子被创造(出生)为灰色,它不会改变,直到鸽子死去。因此,正在使用的用户根本不应该能够根据自己的意愿更改颜色。下面是上述 Bird 类的 getter 和 setter 的实现。
// Java program to demonstrate
// the bird class
// Implementing the bird class
public class Bird {
// Few properties which
// define the bird
String color;
int legs;
// Implementing the getters and
// setters for the color and legs.
public void setColor(String color)
{
this.color = color;
}
public String getColor()
{
return this.color;
}
public void setLegs(String legs)
{
this.legs = legs;
}
public String getLegs()
{
return this.legs;
}
// Few operations which the
// bird performs
public void eat()
{
System.out.println(
"This bird has eaten");
}
public void fly()
{
System.outp.println(
"This bird is flying");
}
}
多态性:多态性这个词由 poly 和 morph 两个词组成,其中 poly 表示许多,morphs 表示形式。在编程中,多态性是一种允许将一个接口用于一类通用动作的特性。在上述鸟和鸽子的概念中,鸽子本质上是鸟。而且,如果将鸟类进一步分类为飞鸟,不会飞的鸟等多个类别,那么鸽子也适合飞鸟的类别。而且,如果将动物类进一步分为食草动物和食肉动物,鸽子又归入食草动物的范畴。因此,多态性的思想是同一个对象采取多种形式的能力。多态性有两种类型:
- 编译时多态:也称为静态多态。这种类型的多态性是通过函数重载或运算符重载来实现的。当我们定义多个具有不同签名的方法并且编译器根据方法签名知道需要执行哪个方法时,就会发生这种情况。
- 运行时多态性:也称为动态方法调度。这是一个在运行时解析对被覆盖方法的函数调用的过程。这种类型的多态性是通过方法覆盖来实现的。当具有相同参数的相同方法被不同的上下文覆盖时,编译器不知道该方法被覆盖。它只是检查该方法是否存在,并在运行时执行已被覆盖的函数。
在Java中,我们还可以向上转换和向下转换对象。这个概念背后的核心思想也是多态性。这个想法是鸟的对象可以具有鸽子的价值,因为它继承了鸟的特征。因此,如果两个对象以下列方式相互扩展,则也可以使用子属性初始化父对象:
Bird b = new Pigeon();
抽象:抽象通常意味着隐藏。在上述鸟和鸽子的场景中,假设有一个用户想看鸽子飞翔。用户只对看到鸽子飞行感兴趣,而不对鸟实际上是如何飞行感兴趣。因此,在上述用户希望让它飞起来的场景中,他只需使用pigeon.fly()调用 fly 方法,其中 pigeon 是鸟鸽的对象。因此,抽象意味着在不考虑背景细节的情况下表示基本特征的艺术。在Java中,抽象是通过使用接口和抽象类来实现的。我们可以使用接口实现完全抽象,而使用抽象类可以实现部分或完全抽象。抽象被认为是重要概念之一的原因是:
- 它降低了查看事物的复杂性。
- 避免代码重复并提高可重用性。
- 由于仅向用户提供重要的详细信息,因此有助于提高应用程序或程序的安全性。