面向对象(上)-封装性的引入

面向对象(上)-封装性的引入

4.7 面相对象特征之一:封装和隐藏

  • 为什么需要封装?封装的作用和含义?

    我要用洗衣机,只需要按一下开关和洗涤模式即可,不需要了解洗衣机的内部构造和洗衣原理。

  • 我们的程序设计追求"高内聚,低耦合"

    高内聚:类的内部数据操作细节自己完成,不允许外部干涉;

    低耦合:仅对外暴露少量的方法用于使用。

  • 隐藏对象内部的复杂性,只对外公开简单的接口。便于外接调用,从而提高系统的可扩展性、可维护性。通俗的说:把该隐藏的隐藏起来,该暴露的暴露出来。

问题的引入

当我们创建一个类的对象以后,我们可以通过"对象.属性"的方式,对对象的属性进行赋值。

这里复制操作是受属性的数据类型和存储范围限制,除此之外没有其他制约条件。

但是实际问题中,我们往往需要给属性复制假如额外的限制,就不能只做属性的申明,需要通过方法添加体现。(eg:setLegs、getLegs)

举例:假设我们有一个类描述"狗",其中有个属性legs表示狗腿的数量。如果只要int legs,那么用户有可能传入负数,显然狗腿数量不可能为负数,需要使用方法对传入的数进行限制,且限制用户直接调用"对象.属性"进行赋值。

java 复制代码
    public static void main(String[] args){
        Dog dog = new Dog();
        // dog.legs = -6;   // 编译报错,'legs' has private access in 'com.example.xu_ni_ping.Dog'
        dog.setLegs(-6);
        dog.getLegs();   // 输出0
        dog.setLegs(4);
        dog.getLegs();   // 输出4
    }
java 复制代码
public class Dog {
    private int legs;   // 设置为私有,防止用户调用

    // 设置腿的数量
    public void setLegs(int l) {
        if (l >= 0) {
            legs = l;
        } else {
            legs = 0;  // 如果传入的值为负数,就设置为0;
            // 或者抛出异常;
        }
    }

    // 获取腿的数量
    public int getLegs() {
        System.out.println(legs);
        return legs;
    }
}

封装性的体现

我们需要避免用户在使用"对象.属性"的方式对属性进行赋值,所以我们需要将属性私有化(private),并提供setLegs和getLegs方法。这就体现出了属性以及方法的封装性。

拓展:封装性的体现包含,属性私有化,提供get和set方法;不对外暴露的私有化方法;单例模式等。

权限修饰符

封装性的体现,需要权限修饰符来配合:

java规定的4种权限,从小到大排序:private、default(缺省时默认)、protected、public

修饰符 类内部 同一个包 不同包的子类 同一个工程
private yes
default yes yes
protected yes yes yes
public yes yes yes yes

4种权限可以用来修饰类以及类的内部结构(属性、方法、构造器、内部类)

  • 对于类:使用default、public;
  • 对于类的内部结构(属性、方法、构造器、内部类):private、default、protected、public都行;

封装性举例

例子:创建程序,在其中定义两个类:Person和PersonTest类。定义如下:用setAge()设置人的合法年龄(0-130),用getAge()返回人的年龄。在PersonTest类种的实例化Person类的对象b,调用setAge()和getAge()方法,体现Java封装性

java 复制代码
    public static void main(String[] args){
        Person person = new Person();
        // person.age = 18;  // 'age' has private access in 'com.example.xu_ni_ping.Person'
        person.setAge(18);
        System.out.println(person.getAge());  // 输出18
        person.setAge(-18);
        System.out.println(person.getAge());    // 运行报错:java.lang.RuntimeException: 传入的年龄非法!at com.example.xu_ni_ping.Person.setAge(Person.java:15)
    }
java 复制代码
public class Person {

    private int age;

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        if (age >= 0 && age <= 130) {
            this.age = age;
        } else {
            throw new RuntimeException("传入的年龄非法!");
        }
    }
}

快速生成set、get方法:

在类的空白处点击鼠标右键。

选择"Generate"。

选择"Getter and Setter"。

选择需要生成getter和setter方法的字段,点击"OK"即可。

相关推荐
脸大是真的好~2 小时前
黑马JAVAWeb-05 JDBC入门-预编译SQL-Mybatis入门-Mybatis日志输出-数据库连接池-增删改查-XML映射配置
java
还算善良_2 小时前
XML签名
xml·java·开发语言
梅梅绵绵冰2 小时前
xml方式实现AOP
xml·java·开发语言
桦说编程3 小时前
Guava 迭代器增强类介绍
java·后端·设计模式
235164 小时前
【JVM】Java为啥能跨平台?JDK/JRE/JVM的关系?
java·开发语言·jvm·spring boot·后端·spring·职场和发展
2401_860319524 小时前
【无标题】
开发语言·学习·rust
courtfu4 小时前
Plugin ‘mysql_native_password‘ is not loaded`
java·后端
枫子有风4 小时前
Go语言流程控制
android·java·golang
小裕哥略帅5 小时前
订单管理--实时算出在途数量、收货数量、到货数量、已发货数量和未发货数量
java·开发语言