【JavaSE】封装、继承与多态

1、封装

1.1简介

  • 在Javase中,封装(Encapsulation)是面向对象编程(OOP)的一个重要概念。
  • 封装的主要目的是隐藏对象的内部状态和信息,只提供必要的公共方法来访问和操作这些状态和信息。
  • 通过封装可以控制对对象内部数据的访问级别,并保护数据不被随意修改,从而提高代码的安全性和可维护性。

1.2特点

  • 信息隐藏:对象的内部状态(即属性或数据成员)被隐藏起来,外部世界只能通过对象提供的方法来访问或修改这些状态。

  • 访问控制:通过访问修饰符(如publicprivateprotected和默认(包级私有))来控制对属性和方法的访问级别。

  • 数据完整性:封装可以确保数据的完整性,因为只能通过对象提供的方法来修改数据,而这些方法通常包含了对数据的验证和逻辑检查。

  • 接口清晰:封装使得对象只暴露必要的接口给外部世界,从而简化了对象的使用,并降低了对象之间的耦合度。

1.3好处

  • 安全性:通过控制对属性的访问级别,可以确保数据不会被恶意修改或误用。

  • 可维护性:当内部实现发生变化时,只需要修改对象内部的方法,而不需要修改使用对象的代码。

  • 灵活性:封装允许我们根据需要改变类的内部实现,而不需要影响使用这个类的代码。

1.4封装实现

在Javase中,封装通常通过以下步骤实现:

  1. 将属性私有化:使用private关键字将类的属性声明为私有的,这样它们只能在类的内部被访问。

  2. 提供公共的getter和setter方法:为了允许外部世界访问和修改私有属性,我们可以提供公共的getter方法来读取属性的值,并提供公共的setter方法来设置属性的值。这些方法可以包含对数据的验证和逻辑检查。

下面是一个简单的示例,演示了如何在Javase中实现封装:

public class Person {  
    // 私有属性  
    private String name;  
    private int age;  
  
    // 公共的getter方法  
    public String getName() {  
        return name;  
    }  
  
    // 公共的setter方法  
    public void setName(String name) {  
        // 可以在这里添加验证逻辑,比如检查name是否为空或长度是否合适  
        this.name = name;  
    }  
  
    // 其他的getter和setter方法...  
    public int getAge() {  
        return age;  
    }  
  
    public void setAge(int age) {  
        // 可以在这里添加验证逻辑,比如检查age是否在合理范围内  
        if (age >= 0) {  
            this.age = age;  
        } else {  
            throw new IllegalArgumentException("Age cannot be negative");  
        }  
    }  
  
    // 其他方法...  
}

2、继承

2.1简介

  • 在Javase中,继承(Inheritance)是面向对象编程的一个重要特性,它允许我们创建一个新的类(称为子类或派生类),这个类继承自一个已存在的类(称为父类或基类)。子类继承父类的属性和方法,从而可以重用父类的代码,并添加新的功能。
  • 继承是指一个类(子类)可以直接使用另一个类(父类)的属性和方法。
  • 子类继承父类后,就拥有了父类声明的所有属性和方法(除了被声明为private的属性和方法)。
  • 子类不能选择性继承父类:子类继承父类时,会继承父类中的所有非私有属性和方法。
  • 构造方法不会被子类继承:但子类可以通过super()关键字调用父类的构造方法。
  • 访问权限:子类只能访问父类中访问权限允许的属性和方法。

2.2好处

  • 代码复用性:通过继承,子类可以重用父类的代码,避免了重复编写相同的代码。
  • 类与类之间的关系:继承使得类与类之间产生了关系,为多态提供了前提。
  • 快速创建新类:通过继承可以快速创建新的类,提高开发效率。

2.3特点

  • 单继承:Java只支持单继承,即一个子类只能有一个直接父类。
  • 多层继承:Java支持多层(多重)继承,即一个类可以间接继承多个类(通过继承链)。
  • 不支持多继承:Java不直接支持多继承,即一个子类不能直接继承多个父类。但Java通过接口(Interface)的方式实现了类似多继承的功能。

2.4语法格式

在Java中,使用extends关键字来声明一个类继承另一个类。例如:

class Parent {  
    // 父类的属性和方法  
}  
  
class Child extends Parent {  
    // 子类继承父类的属性和方法,并可以添加自己的属性和方法  
}

2.5子类实例化过程

  •  父类的构造方法,不能被子继承
  • 在子类的构造方法中,调用了父类的构造方法
  •  如果父类有无参的构造方法,子类super()可以省略
  • 如果父类中没有无参的构造方法,子类super(参数)不可以省略
  • 如果使用super()显式地调用父类的构造方法,要求必须写在子类构造方法中的第一行
  • 子类的构造方法中,不能同时出现super()this()

2.6属性隐藏

  • 在父类中定义一个属性,在子类中定义了一个同名的属性,在子类中访问,会隐藏父类的属性
  • 在子类中,有两个同名属性,一个是继承自父类的,使用super.属性名访问,一个是子类自己的,使用this.属性名访问
  • 在方法中,如果访问到属性,继承自父类的方法,使用的是父类的属性,子类自己的方法,使用的是子类属性。
  • 如果父类中有一个静态变量,则被所有子类所共享,其中一个子类修改了值,其他子类访问也是修改后的值。如果子类自己写了一个同名的静态变量,则子类中访问的是自己的变量,不再是父类变量

3、多态

3.1定义

  • 在Javase中,多态(Polymorphism)是面向对象编程的核心特性之一,它允许我们在不改变现有代码结构的情况下,通过不同的对象执行相同的行为但产生不同的结果。
  • 多态指的是同一个行为(方法),在创建不同对象去进行的时候会产生不同的效果。
  • 简单来说,就是同一件事情,发生在不同对象身上,就会产生不同的结果。

3.2实现条件

  • 必须在继承体系下:多态是建立在继承的基础之上的,必须存在父类和子类之间的关系。
  • 子类必须重写父类中的方法:子类需要覆盖或重写父类中的方法,以实现不同的行为。
  • 通过父类的引用调用重写的方法:在实际代码中,我们通过父类类型的变量来引用子类对象,并调用其重写后的方法。

3.3体现

  • 在代码运行时:当传递不同对象给父类引用时,会调用对应类中的方法,实现不同的行为。
  • 方法重写:子类重写父类中的方法,是实现多态的关键步骤。

3.4优点

  • 提高了代码的复用性和灵活性:通过多态,我们可以编写通用的代码,适用于不同的对象类型。
  • 降低了代码的耦合度:多态使得代码更加松散,降低了类之间的依赖关系。

3.5里氏代换原则

3.5.1定义

  • 里氏代换原则指出:“如果程序中的对象使用的是基类(超类)的话,那么无论是使用基类对象还是其子类对象,程序的行为应该是一样的。”这意味着,在软件系统中,如果一个基类对象可以在程序的某处被使用,那么其子类对象也可以在该处被替换使用,且不会改变程序的正确性和一致性。

3.5.2基本原则

  • 父类出现的地方,子类一定可以出现
  • 子类出现的地方,父类不一定可以出现

3.6示例

  • 假设我们有一个Animal类(父类),它有一个eat()方法。然后我们有两个子类Dog和Cat,它们都继承自Animal类并重写了eat()方法。现在,我们可以通过一个Animal类型的变量来引用Dog或Cat对象,并调用其eat()方法,实现不同的吃食行为。
public class Animal {  
    public void eat() {  
        System.out.println("Animal is eating");  
    }  
}  
  
public class Dog extends Animal {  
    @Override  
    public void eat() {  
        System.out.println("Dog is eating dog food");  
    }  
}  
  
public class Cat extends Animal {  
    @Override  
    public void eat() {  
        System.out.println("Cat is eating fish");  
    }  
}  
  
public class Test {  
    public static void main(String[] args) {  
        Animal animal1 = new Dog(); // Animal类型引用指向Dog对象  
        Animal animal2 = new Cat(); // Animal类型引用指向Cat对象  
        animal1.eat(); // 输出:Dog is eating dog food  
        animal2.eat(); // 输出:Cat is eating fish  
    }  
}

你可能感兴趣的:(JavaSE,java,开发语言)