面向对象的特征之一:封装

一.封装性

1.面向对象这个编程思想,有三个基本特征:

① 封装

② 继承

③ 多态

2.什么是封装性?

生活中,快递包裹,通常需要用袋子或箱子装起来。

目的:① 包含的内部商品,不会被损坏

           ② 可以包含隐私

           ③ 运输更方便

所以,代码也要考虑这些因素:

① 隐私 -> 安全,当某个类的代码,内部某些成员不希望外部知晓,或者随意的更改,那么就可以进行适当的封装

② 外部使用更方便

比如:生活中,洗衣机,只会留出几个简单的按钮和进水口,出水口,放衣服的入口这几个,它隐藏了内部复杂的结构。

代码中,String类,它内部的结构和实现是很复杂的,但是我们就算不是特别清除每一个内部实现,也不影响我们简单的使用

把代码控制在它的合理的可见性范围内,就是封装。

3.如何实现封装?

必须依赖于权限修饰符,或者又称为访问控制修饰符。

4.权限修饰符有哪些?

public,protected,缺省,private

                              本类                本包的其他类                其他包的子类中            其他包的非子类

private                     √                             ×                                     ×                                  ×

缺省                         √                             √                                     ×                                  ×

protected                 √                             √                                     √                                   ×

public                       √                             √                                     √                                   √ 

5.权限修饰符的使用要注意

① 如果权限修饰符是在class前面(这里暂不讨论内部类),只能是public或缺省

② 如果权限修饰符是在类的成员前面(成员变量,成员方法等),四种都可以

二.成员变量选择那种权限修饰符?

1.实际应用中,习惯上,先声明为private。称为属性私有化。

但是如果确实这个成员变量需要扩大它的可见性范围,那么可以把private修改为其他合适的修饰符。

例如:扩大到本包,那么就是缺省的。

例如:扩大到其他包的子类中,那么就是protected

例如:扩大到其他包的非子类中,那么就是public

2.为什么要使用权限修饰符?

因为属性其实就是代表对象的“数据”,那么对象的数据是非常重要的,不应该完全暴露,至少要可控。

3.如何使用私有化的属性?

如果这个属性确实要被外部使用,需要提供get或set方法。

get方法:供调用者获取属性值的方法

set方法:供调用者修改属性值的方法

4.get/set方法要注意的地方:

① 如果方法中有局部变量(也就是形参)与对象的实例变量“重名”,那么需要在实例变量的前面加“this.”。如果没有重名问题,在实例变量前面可以加“this.”,也可以不加“this.”。

② get/set的方法名,通常都是

get + 属性名,并且属性名的首字母大写

set + 属性名,并且属性名的首字母大写

③ 如果属性是boolean类型,那么它对应的方法,就会把get单词换成  is

Student类代码:

package com.atguigu.encapsulability;
 
public class Student {
    private String name;
    private int score;
    private int age;
    private boolean marry;
 
    //快捷键,自动生成get/set
    //在要写get/set方法的位置,鼠标的光标不要定位错位置了
    //按快捷键 Alt + Insert,部分同学需要同时按Fn
 
    public String getName() {
        return name;
    }
 
    public void setName(String name) {
        this.name = name;
    }
 
    public int getScore() {
        return score;
    }
 
    public void setScore(int score) {
        this.score = score;
    }
 
    public int getAge() {
        return age;
    }
 
    public void setAge(int age) {
        //加条件判断,加逻辑的控制
        if(age<=20 || age>=35){
            return;
//            throw new IllegalArgumentException(age +"非法");
        }
        this.age = age;
    }
 
    public boolean isMarry() {
        return marry;
    }
 
    public void setMarry(boolean marry) {
        this.marry = marry;
    }
}

对属性加上权限修饰符的话,也就是属性私有化,可以保证属性(数据)的安全,比如说设置属性值的时候,属性私有化就可以在set方法上加条件判断,看上述代码。

TestField类代码:

package com.atguigu.encapsulability;

public class TestField {
    public static void main(String[] args) {
        Student s1 = new Student();
/*        s1.name = "张三";
        s1.score = 89;
        s1.age = 23;
        //以上代码正常使用没问题,但是如果出现以下代码
        s1.score = -89;
        s1.age = -23;//没有设置权限修饰符,可以随便更改属性值(数据)
        //这样写,逻辑上有问题,语法上没法控制*/
 
        //这里是调用者的角色,调用s1学生对象的姓名name的get和set
        System.out.println("修改之前,姓名:" + s1.getName());
        s1.setName("张三");
        System.out.println("修改之后,姓名:" + s1.getName());
 
        System.out.println("修改之前,年龄:" + s1.getAge()) ;
        s1.setAge(-23);
        System.out.println("修改之后,年龄:" + s1.getAge()) ;
    }
}

练习1:

(1)定义矩形类Rectangle,

- 声明实例变量长和宽,全部私有化private,

- 提供相应的get/set方法,如果set方法的参数值<=0,则提示矩形的长和宽必须是正数

- 声明public double area(),返回矩形面积

- 声明public double perimeter():返回矩形的周长

- 声明public String getInfo():返回矩形的长、宽、面积、周长信息

(2)测试类的main中创建一个可以装3个矩形对象的数组,并调用set方法为对象的属性赋值,依次长是8,7,6,宽是2,3,4

- 遍历输出矩形对象数组

- 按照矩形对象的length属性值从小到大排序后,遍历输出矩形对象数组

- 按照矩形对象的面积从小到大排序后,遍历输出矩形对象数组

编写代码的习惯:先写所有的成员变量的声明,再写方法

Rectangle类代码:

public class Rectangle {
    private double length;
    private double width;
 
    public double getLength() {
        return length;
    }
 
    public void setLength(double length) {
        if(length<=0){
            System.out.println("长方形的长必须是正数");
            return;//结束当前方法的执行,那么 this.length = length;就不执行了
        }
        this.length = length;
    }
 
    public double getWidth() {
        return width;
    }
 
    public void setWidth(double width) {
        if(width<=0){
            System.out.println("长方形的宽必须是正数");
            return;//结束当前方法的执行,那么 this.width = width;就不执行了
        }
        this.width = width;
    }
 
    public double area(){
        return length * width;
    }
    public double perimeter(){
        return 2 * (length + width);
    }
    public String getInfo(){
        return "长:" + length +",宽:" + width +",面积:" + area() +",周长:" + perimeter();
    }
}

TestRectangle类代码:

public class TestRectangle {
    public static void main(String[] args) {
        Rectangle[] arr = new Rectangle[3];
 
        System.out.println("排序之前:");
        for (int i = 0; i < arr.length; i++) {
            arr[i] = new Rectangle();
            arr[i].setLength(8-i);
            arr[i].setWidth(2+i);
            System.out.println(arr[i].getInfo());
        }
 
        System.out.println("按照length从小到大排序:");
        for(int i = 1; i < arr.length; i++) {
            for(int j = 0; j < arr.length-i; j++) {
                if(arr[j].getLength() > arr[j+1].getLength()){
                    Rectangle temp = arr[j];
                    arr[j] = arr[j+1];
                    arr[j+1] = temp;
                 }
            }
        }
 
       for(int i = 0; i < arr.length; i++) {
           System.out.println(arr[i].getInfo());
       }
 
        System.out.println("按照面积从小到大排序:");
       for(int i = 1; i < arr.length; i++) {
           for(int j = 0; j < arr.length-i; j++) {
               if(arr[j].area() > arr[j+1].area()){
                   Rectangle temp = arr[j];
                   arr[j] = arr[j+1];
                   arr[j+1] = temp;
                }
           }
       }
        
       for(int i = 0; i < arr.length; i++) {
           System.out.println(arr[i].getInfo());
       }
 
    }
}
  • 2
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值