Java面向对象编程三大特征 - 封装

Java面向对象编程三大特征 - 封装

本文关键字:Java、面向对象、三大特征、封装
封装是面向对象编程中的三大特征之一,在对封装性进行解释时我们有必要先了解一些面向对象的思想,以及相关的概念。当我们想要去描述一系列的关系时我们要用到的最基本结构就是类,其中存在着成员变量和方法,用于记录属性和表达行为,相关知识请进传送门:Java中的基本操作单元 - 类和对象

一、名词解读

为了解释封装的概念和作用,需要先来了解一下几个相关的概念,这有助于我们接下来的理解。

1. 权限修饰符

当我们在一个类中定义成员变量时,会指定一个变量的类型,除此之外,还会有修饰符的部分,在此给出定义成员变量的规范格式:

// 定义变量
[修饰符] 变量类型 变量名称;
[修饰符] 变量类型 变量名称 = 初始值;

修饰符起到的作用从字面就可以解释,起到一个修饰和限定的作用,可以使用在成员变量之前的修饰符可以是:publicprotectedprivate、final、static。
修饰符与修饰符之间的顺序没有强制要求,其中public、protected、private被称为权限修饰符,可以用来限定类的属性和方法的访问权限,指明在哪些包的哪些类中能够调用到这些属性或方法,是一种一定会存在的修饰符。需要注意的是,这三个单词不能同时出现,当这三个单词都不出现的时候会被认为是默认访问权限,所以权限修饰符一共有四种:private、默认、protected、public。

2. 权限对应关系表

  • private:私有权限,只能在定义的类中访问,在其他类中创建的实例均无法访问
  • 默认:同包可访问权限,在没有声明权限修饰符时为默认权限,允许在同包的其他类访问
  • protected:受保护权限,允许有继承关系的子类访问
  • public:公共权限,允许任何类访问

3. 属性访问

由于权限修饰符在封装特性中的作用只是实现封装性的一种途径,所以在这里只演示private与public的作用,权限修饰符的其他作用将在后续的文章中继续介绍。

src
└──edu
    └──sandtower
        └──bean
            │    Person.java
        └──test
            │    Test.java

以上为实体类与测试类所在的目录结构,Person实体类所在包:edu.sandtower.bean,Test测试类所在包:edu.sandtower.test,相应代码如下:

package edu.sandtower.bean;

public class Person{
    // 声明公开属性
    public String name;
    // 声明私有属性
    private double money;
}
package edu.sandtower.test;

import edu.sandtower.bean.Person;

public class Test{
    public static void main(String[] args){
        // 在test包中的Test类中创建Person实例
        Person person = new Person();
        person.name = "小张";// 编译通过,可以访问name属性
        person.money = 500.0;// 编译失败,无法访问money属性
    }
}

从上面的例子可以看出,虽然依然是使用Person自己的实例在进行属性的调用,但是我们是在另外一个包中的类发生的调用,所以是不能够访问到private修饰的属性的,在刚开始学习时一定要注意区分。

二、概念阐释

1. 封装有什么用

通过使用权限修饰符,我们可以限定类的成员的被访问权限,那为什么要这样做呢?在很多场景下,我们需要确保我们对属性值的操作均是有效操作,不能违背某些规则。
比如,我们定义了一个Person类,具有name和money两个属性,在买东西时需要扣掉相应的金额,原始写法如下:

public class Person{
    public String name;
    public double money;
}
public class Test{
    public static void main(String[] args){
        Person person = new Person();
        person.money = 500;// 初始金额500元
        System.out.println("购买一张桌子,花费200元");
        person.money -= 200;
        System.out.println("购买二手PSP,花费350元");
        person.money -= 350;
        System.out.println("目前余额为:" + person.money);// -50
    }
}

可以看到,经过代码操作以后可能会导致money的属性为负。看官甲:你自己不加判断赖代码?没错,这个问题我们可以增加判断代码来解决,由于这个操作是对money属性值的操作,我们将它封装成一个方法写在实体类中,于是有了改进之后的代码:

public class Person{
    public String name;
    public double money;

    // 定义一个方法,用于设置money属性的值
    public void setMoney(double money){
        if(money >= 0){
            this.money = money;
        }
    }
}
public class Test{
    public static void main(String[] args){
        Person person = new Person();
        person.money = 500;// 初始金额500元
        System.out.println("购买一张桌子,花费200元");
        person.setMoney(person.money - 200);
        System.out.println("购买二手PSP,花费350元");
        person.setMoney(person.money - 300);
        System.out.println("目前余额为:" + person.money);// 300
    }
}

经过上面的改进,我们可以确保money的值不为负数,同时可以看到,当在实体类中定义方法后,使用者需要修改属性值时直接调用方法就可以保证不出问题。但是由于属性值依然可以被直接访问,还不能保证万无一失,于是我们利用权限修饰符使得变量不能被直接访问,同时需要定义一个能够取得属性值的方法。

public class Person{
    public String name;
    // 声明money属性为private权限
    private double money;

    // 定义一个方法,用于设置money属性的值
    public void setMoney(double money){
        if(money >= 0){
            this.money = money;
        }
    }
    // 定义一个方法,用于获取money属性的值
    public double getMoney(){
        return this.money;
    }
}
public class Test{
    public static void main(String[] args){
        Person person = new Person();
        person.money = 500;// 初始金额500元
        System.out.println("购买一张桌子,花费200元");
        person.setMoney(person.getMoney() - 200);
        System.out.println("购买二手PSP,花费350元");
        person.setMoney(person.getMoney() - 300);
        System.out.println("目前余额为:" + person.getMoney());// 300
    }
}

通过以上的案例,我们可以看到进行封装有以下几个作用:

  • 防止类的属性被外部代码随意的修改和访问,保证数据的完备性
  • 将对属性的操作转换为方法,更加灵活和安全
  • 使用封装可以隐藏实现的细节:使用者只需要作用,不需要知道过程
  • 在类的定义结构中修改,提高了代码的可维护性,同时又可以不影响外部的使用
  • 通过封装方法可以有效减少耦合
    • 耦合:模块与模块之间,代码与代码之间的关联程度,对属性封装后,和调用相关的代码就会变得相对简单,可以降低耦合

2. 如何进行封装

在进行封装时都是出于对属性保护的考虑,可以按照以下两个步骤来进行:

  • 使用权限修饰符

    • 使用private作用在属性上,关闭直接访问的入口
    • 使用public作用在方法上,提供调用的入口
  • 定义与属性存取相关的方法

在属性关闭后,我们需要通过方法来获取属性的值以及对属性值进行修改。由于有了方法结构,我们就可以对存入的数据进行判断,对不符合逻辑的数据进行处理。

3. 常规封装方法

明白了封装的作用后,我们可以通过自定义方法的方式完成对属性的封装。封装方法和类中定义的其他方法在结构上没有任何的区别,同样都是普通的方法,区别主要在于体现在用途方面:

  • 普通方法主要表达该类所能产生的行为
  • 封装方法主要为属性的访问和使用提供了一个入口,作用相对单一

在进入到框架的学习之后,很多对实体类属性自动赋值的操作都是通过调用封装方法实现的,所以我们必须要知道常规封装方法的名称定义和类型设置规则。
对于属性来说我们只会进行两种操作:存和取。那么相应的封装方法应该有一对儿

  • get代表取用:既然是取值,那么就要把属性值进行返回,方法的返回值类型与属性类型相同
  • set代表存储:既然是存值,那么就要在参数列表中接收想要存入的值,类型与属性类型相同

对于命名方面只要遵从驼峰命名法就好,以get或set开头,大写属性名称的首字母,其余不变,看下面一个例子:

public class Person{
    // 使用private声明属性
    private String name;
    private double money;

    // 使用public声明方法,作为操作属性的入口
    public void setName(String name){
        this.name = name;
    }
    public String getName(){
        return this.name;
    }
    public void setMoney(double money){
        // 如有需要,可以在方法中可以自定义其他逻辑
        this.money = money;
    }
    public double getMoney(){
        return this.money;
    }
}

由于常规封装方法定义的格式和名称都相对固定,所以一般的编译器都自带自动生成封装方法的功能,这样既方便又能降低出错率,大家一定要掌握。

  • Eclipse:

属性定义完成后,选择source菜单 -> Generate Getters and Setters...

点击Select All(选择所有属性) -> Generate

  • IDEA:

与Eclipse类似,在定义好类的私有属性后,使用快捷键:Alt + Insert

可以一次性选择多个属性 -> 点击OK

原文地址:https://blog.51cto.com/10984944/2481918

时间: 03-26

Java面向对象编程三大特征 - 封装的相关文章

面向对象的三大特征——封装、继承、多态

接触过面向对象的人都知道面向对象有三大特征,分别是封装.继承和多态.这三者分别指的是什么,为什么是这哥仨,使用他们有什么好处,我们来梳理一下. 封装 原则:隐藏对象的属性和实现细节,仅对外提供公共访问方式. 好处: ①将变化隔离. ②便于使用. ③提高重用性. ④提高安全性. Demo1: 比如一个学生类:他具有姓名和年龄两个属性,但是为了提高安全性和重用性,便于使用,我们将其封装起来. public class Student { private String name; private in

Java面向对象的三大特征:封装、继承和多态

封装: 封装就是把抽象出的数据和对数据的操作封装在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(成员方法),才能对数据进行操作. 封装--访问控制修饰符(Java提供四种访问控制修饰符) 1.public  :公开级别,范围最广的. 2.protected:受保护级别,对子类和同一个包内的类公开. 3.default:默认级别,可以不写修饰符号,向同一个包的类公开. 4.private:私有级别,只有类本身可以访问,不对外公开. 继承: 继承可以解决代码复用,让我们的编程更加靠近人

php面向对象的三大特征

1.面向对象的三大特征:封装.继承.多态.(抽象(扩展的))2.00A:分析,OOD:设计,OOP:编程.3.封装:信息隐蔽,封装,所有的函数和方法,类中的属性和行为也是封装. 三个访问修饰符public.protected.private也是封装.4.public 公共的 谁都可以用,也可以修改:protected 受保护的 只有自己和后代可以使用和修改: private 私有的 只有自己可以使用和修改:5.继承: 扩展父类的内容,注意只能继承public和protected修饰的内容,而pr

java面向对象编程(七)--四大特征之多态

1.多态概念 多态性是对象多种表现形式的体现.比如我们说"宠物"这个对象,它就有很多不同的表达或实现,比如有小猫.小狗.蜥蜴等等.那么我到宠物店说"请给我一只宠物",服务员给我小猫.小狗或者蜥蜴都可以,我们就说"宠物"这个对象就具备多态性. java中的多态,就是指一个引用(类型)在不同情况下的多种状态.也可以理解成,多态是指通过指向父类的指针,来调用在不同子类中实现的方法.也可以理解为"一个接口,多个方法". 实现多态有两种

java面向对象编程(六)--四大特征之继承、方法重载和方法覆盖

一.继承 1.继承的概念 继承可以解决代码复用,让我们的编程更加靠近人类思维.当多个类存在相同的属性(变量)和方法时,可以从这些类中抽象出父类,在父类中定义这些相同的属性和方法,所有的子类不需要重新定义这些属性和方法,只需要通过extends语句来声明继承父类.语法如下: class 子类 extends 父类 这样,子类就会自动拥有父类定义的某些属性和方法.另外,并不是父类的所有属性.方法都可以被子类继承.父类的public修饰符的属性和方法,protected修饰符的属性和方法,默认修饰符属

Java面向对象编程(一)

由于常常将Java和C++面向对象编程的原则搞乱,所以这次把相关要点分别总结一下,本文主要总结Java面向对象编程. 面向对象编程的三大特性是:继承性(inheritance), 多态性(polymorphism)和封装性(encapsulation). 一. 继承性 [类修饰词列表] class 类名 [extends 父类名] [implements 借口列表名] { 类体 } class Employee { public int workYear; public Employee() {

聊一聊面向对象的三大特征

学习Java语言程序设计也有一段时间了.现在我想对封装.继承和多态,在Java中面向对象的三大特征,总结一下我的理解,不妥当的地方望大家包涵.  封装.给我的感觉封装就是一个包装,一个代码是否健壮,与用不用封装有很大的关系,封装就像是包裹一个礼物,不仅让礼物看起来更加精美,而且还完善了内容.请看代码: class Person {     private String name;     private int age;     public void say() {         Syste

7 面向对象的三大特征

面向对象的三大特征为:封装.继承.多态. 1 封装(encapsulation) 1.1  广义上的封装就是包装,可以将方法看作是对为完成特定功能的代码的封装,可以把类看作对属性和方法的封装.... 狭义上的封装:将属性私有化,然后提供公有的getter和setter方法以供访问. 封装的优点: 1)隐藏了实现细节,简化开发  2)安全  3)提高了代码的可维护性和可扩展性. 步骤: 1)将属性私有化,将修饰符修改private的 2)提供公有的访问方法:getter方法:取值,setter方法

JAVA学习(五):Java面向对象编程基础

Java面向对象编程基础 面向对象(Object oriented programming,OOP)技术是一种强有力的软件开发方法,它採用数据抽象与信息隐藏技术,来使软件开发简单化,以达到代码重用的目的. 1.OOP的3个特性(封装.继承和多态性) 封装是类的基础.指把类的相关实现细节隐藏起来,在类中将数据和实现操作的代码集中起来放在对象的内部.调用这些类时仅仅需直接使用类预留的接口就能够了. 继承提供了子类自己主动拥有父类数据结构和方法的机制.它表示类之间的一种关系. 多态指使一个对象被看成还

Java面向对象的三大特点

Java面向对象的三大特点:继承.封装.多态 继承 继承的起源 使用“is a”关系判断继承 Java中继承的实现 关键字:extends 实例化子对象 单继承和多继承 子类继承父类.父类还可以继承上一个类,称为传递继承. Dog extends Animal: Animal extends ShengWu: 所有类的根类Object 即object类是所有类的父类,object中所有的方法其他类都可以直接调用 方法重写 父类方法   Public void jiao(){system.out.