Java基础34 面向对象三大特征之封装

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

封装(encapsulation)

封装就是把抽象出的数据(属性)和对数据的操作(方法)聚集在一起,数据被保护在内部,程序的其他部分只有通过被授权的操作(方法),才能对数据进行操作。

封装的好处

  1. 隐藏实现细节
  2. 可以对数据进行验证,保证安全合理

1.封装的实现步骤

  1. )将属性进行私有化【不能直接修改属性】
  2. )提供一个公共(public)的set方法,用于对属性判断并赋值
public void setXxx(){  //Xxx表示某个属性
    //加入数据验证的业务逻辑
    属性 = 参数名;
}
  1. )提供一个公共(public)的get方法,用于获取属性的值
public 数据类型 getXxx(){ //权限判断,Xxx表示某个属性
   return xx;
}

2.封装的使用

通过一个例子来说明封装的使用方法:

编写一个程序,查看人的年龄、工资、工作等。
要求:
①. 不能随便查看别人的年龄,工资等隐私,
②. 对设置的年龄进行合理的验证。年龄合理就给设置值,否则就给默认值。
③. 年龄必须在1-120之间,年龄工资不能直接查看,name的长度在2-6之间。

代码实现:

public class Encapsulation001{
    public static void main(String[] args){
        Person person = new Person();
        person.setName("zywoo");
        person.setAge(18);
        person.setSalary(3000);
        System.out.println(person.info());
    }
}

public class Person{
    public String name;
    private int age; //年龄
    private double salary; //工资

    public String getName(){
        return name;
    }
    public void setName(String name){
        //加入对数据的校验
        if(name.length() >=2 && name.length() <=6 ){
            this.name = name;
        } else {
            System.out.println("名字长度不符,在2-6个字符之间。");
        }
        
    }
    public int getAge(){
        return age;
    }
    public void setAge(int age){
        //判断年龄范围
        if(age >= 1 && age <= 120){ //合理范围
            this.age = age;
        } else{
            System.out.println("年龄设置不符合要求,需要在 1-120 之间");
            this.age = 18; //超出范围后给默认年龄
        }
    }
    public double getSalary(){
        return salary;
    }
    public void setSalary(double salary){
        //可以在这里增加对当前对象的权限判断
        this.salary = salary;
    }
    //写一个方法,返回属性信息
    public String info(){
        return  name + " 的信息为:age=" + age + " 薪水=" + salary;
    }
}

Console:
zywoo 的信息为:age=18 薪水=3000.0

3.封装与构造器

还是以上一段代码为例,我在程序中加入构造器:

public class Person{
    public String name;
    private int age; //年龄
    private double salary; //工资
    
    //无参构造器
    public Person(){
    }

    public Person(String name,int age,double salary){
        this.name = name;
        this.age = age;
        this.salary = salary;
    } 

    public String getName(){
        return name;
    }
    public void setName(String name){
        //加入对数据的校验
        if(name.length() >=2 && name.length() <=6 ){
            this.name = name;
        } else {
            System.out.println("名字长度不符,在2-6个字符之间。");
        }
        
    }
    public int getAge(){
        return age;
    }
    public void setAge(int age){
        //判断年龄范围
        if(age >= 1 && age <= 120){ //合理范围
            this.age = age;
        } else{
            System.out.println("年龄设置不符合要求,需要在 1-120 之间");
            this.age = 18; //超出范围后给默认年龄
        }
    }
    public double getSalary(){
        return salary;
    }
    public void setSalary(double salary){
        //可以在这里增加对当前对象的权限判断
        this.salary = salary;
    }
    //写一个方法,返回属性信息
    public String info(){
        return name + " 的信息为:age=" + age + " 薪水=" + salary;
    }
}

如果我们在创建对象时,直接传参会发生什么?

public class Encapsulation001{
    public static void main(String[] args){
        Person person = new Person("zywoo",2000,3000);
        System.out.println(person.info());
    }
}

Console:
zywoo 的信息为:age=2000 薪水=3000.0

从上面的代码可以看出,如果使用构造器的话,可以直接避开set方法的保护机制,那我们要怎样防止这种情况发生?那就是直接把set方法写在构造器中,如下所示:

public Person(String name,int age,double salary){
    this.setName(name);
    this.setAge(age);
    this.setSalary(salary);
}

这次再输出(“zywoo”,2000,3000),就会提示错误信息:

Console:
年龄设置不符合要求,需要在 1-120 之间
zywoo 的信息为:age=18 薪水=3000.0

所以,一般添加构造器后,最好把防护机制添加进构造器中,防止直接使用构造器绕过防护机制

4.封装课后练习

创建程序,在其中定义两个类:Account和AccountTest类体会Java的封装性。

  1. Account类要求具有属性:姓名(长度为2位3位或4位)、余额(必须 > 20)、密码(必须是六位),如果不满足,则给出提示信息,并给默认值
  2. 通过setXxx的方法给Account的属性赋值。
  3. 在AccountTest中测试

提示:
String name = " ";
int len = name.length();

代码实现:

Account类

public class Account {
        private String name;
        private double balance;
        private String password;

        public Account(){

        }

        public Account(String name,double balance,String password){
//            this.name = name;
//            this.balance = balance;
//            this.password = password;
            this.setName(name);
            this.setPassword(password);
            this.setBalance(balance);
        }


        public String getName() {
            return name;
        }

        public void setName(String name) {
            if (name.length() >= 2 && name.length() <= 4) {
                this.name = name;
            } else {
                System.out.println("名字长度不符,在2-4个字符之间。");
                this.name = "ccc";
            }
        }

        public double getBalance() {
                return balance;
        }

        public void setBalance (double balance){
            if (balance>20) {
                this.balance = balance;
            } else {
                System.out.println("余额必须大于20");
                this.balance = 20;
            }
        }

        public String getPassword(){
            return password;
        }

        public void setPassword(String password){
            if(password.length() == 6) {
                this.password = password;
            } else {
                System.out.println("密码必须为6位");
                this.password = "123456";
            }
        }

        public String info(){
            return name + " 的信息为:余额=" + balance + " 密码=" + password;
        }
    }
}

AccountTest类

public class AccountTest{
   public static void main(String[] args){

//            Account p = new Account();
//            p.setName("woo");
//            p.setBalance(300);
//            p.setPassword("123456");
//            System.out.println(p.info());

            Account p = new Account("woo",300,"1234567");
            System.out.println(p.info());
        }
}

输出:

Console:
密码必须为6位
woo 的信息为:余额=300.0 密码=123456
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值