封装与构造方法

发布时间:2026/5/17 10:14:00

封装与构造方法 封装与构造方法一、封装Encapsulation1. 封装的核心思想封装是面向对象三大特性之一核心是 “隐藏内部细节对外提供可控访问”。通过限制属性 / 方法的访问范围避免外部直接操作导致的数据不安全问题同时通过自定义方法实现对数据的校验和控制。2、访问权限修饰符public 公开的整个项目内都可以访问可以修饰类 方法 属性private 私有的只能在自己的类中访问只能修饰类中成员 属性 方法protected 受保护的只能修饰类中的成员属性 方法缺省不写 只能在本包中访问可以修饰类 属性 方法可以通过给属性以及方法添加访问权限修饰符来限制属性和方法的访问范围我们直接通过对象名 调用属性赋值的代码 比较直接没有容错检查空间一旦赋值不管这个值是否符合属性的需求同样也会赋上值比如给 age 赋值一个负数给电话号码 赋值一个14位数3. 封装的实现set/get 方法set 方法赋值 数据校验用于给私有属性赋值可在方法内添加数据合法性校验避免无效数据赋值格式public void set属性名(参数类型 参数名) { 校验逻辑; 属性名 参数名; }get 方法获取属性值用于返回私有属性的值外部无法直接访问属性只能通过 get 方法获取格式public 属性类型 get属性名() { return 属性名; }举例(Student 类)publicclassStudent{// 属性私有化publicStringname;// public修饰全项目可访问privateintage;// private修饰仅本类可访问intid;// 缺省修饰仅本包可访问// setAge给age赋值添加负数校验publicvoidsetAge(intage1){if(age10){System.out.println(输入的年龄不合法~);}else{ageage1;}}// getAge获取age的值publicintgetAge(){returnage;}// 展示信息publicvoidshowInfo(){System.out.println(姓名name年龄age学号id);}}4. 封装的访问测试不同包 / 类中访问封装属性的差异// 不同包的Main类publicclassMain{publicstaticvoidmain(String[]args){StudentstunewStudent();stu.name张三;// public属性可直接访问// stu.age 18; // private属性编译报错stu.setAge(-18);// 通过set方法赋值触发校验// stu.id 1001; // 缺省属性不同包无法访问intagestu.getAge();// 通过get方法获取age值}}二、构造方法Constructor1、定义构造方法是类的特殊方法用于创建对象时初始化属性必须满足方法名与类名完全一致 无返回值类型连 void 都不能写 可重载多个构造方法参数列表不同2.规则每个类默认隐式提供一个 “无参构造方法”若手动编写了构造方法无论有无参数默认无参构造方法会被覆盖3.使用场景创建对象时直接初始化属性替代多次调用 set 方法可在构造方法中调用 set 方法复用数据校验逻辑举例(User 类)publicclassUser{// 私有属性privateStringuserName;// 用户名: 至少要求2个字符到16个字符之间privateStringpassword;// 密码: 6-16位 只能包含字母和数字privateStringphone;// 手机号11位数字符号privateStringemail;// 邮箱 必须包含一个符号 至少6个字符 账户名域名 域名 xx.xx ac.cnprivateStringaddress;// 地址 包含 省/市/区 的字眼privateintid;// 正整数privateintage;// 也不能为负数 0-150// 空参构造方法publicUser(){System.out.println(无参构造方法);}// 带参构造方法publicUser(StringuserName,Stringpassword,Stringphone,Stringemail,Stringaddress,intid,intage){this.setUserName(userName);this.setPassword(password);this.setPhone(phone);this.setEmail(email);this.setAddress(address);this.setId(id);this.setAge(age);}}4. 构造方法的调用staticvoidmain(){//空参构造UserusernewUser();user.setUserName(k);user.setPassword(12345);user.setPhone(1504187028);user.setEmail(com);user.setAddress(武汉);user.setId(-2026);user.setAge(200);}publicclassMain{staticvoidmain(){// 使用带参数的构造方法创建对象 直接给所有的属性一行赋完值UserusernewUser(kyq,123456,15041870289,123qq.com,湖北省武汉市蔡甸区,2026,20);user.showInfo();// 直接展示初始化后的属性}}三、核心总结封装的价值保护数据安全通过 set/get 方法实现数据校验避免非法值访问修饰符属性私有化private是封装的基础public 方法对外提供访问入口构造方法简化对象初始化可复用 set 方法的校验逻辑避免重复代码this 关键字在构造方法 / 成员方法中用于区分参数名和属性名指代当前对象四、注意事项私有化属性后外部必须通过 set/get 方法访问直接赋值会编译报错构造方法不能有返回值否则会被识别为普通方法set 方法的参数名建议与属性名区分如 age1或通过 this 关键字区分复杂校验逻辑如密码、邮箱建议写在 set 方法中构造方法直接调用 set 方法避免代码冗余五、限制属性代码及遇到的问题publicvoidsetUserName(StringuserName){if(userName!null){intlenuserName.length();if(len2len16){this.userNameuserName;}else{System.out.println(用户名长度必须在2-16位之间);}}}publicStringgetUserName(){returnuserName;}publicvoidsetPassword(Stringpassword){if(password!null){intlenpassword.length();// 获取字符串的长度if(len6len16){// 字符串进行遍历 取出每个字符进行判断intl0;for(inti0;ilen;i){// 遍历字符串 获取每个字符charchpassword.charAt(i);// 根据位置获取每个单独的字符// ASCII 码表if(ch0ch9||chachz||chAchZ){l;}else{System.out.println(密码中不能包含除字母和数字之外的字符~);break;}}if(llen){this.passwordpassword;// 进行赋值}}else{System.out.println(密码长度必须在6-16位之间~);}}}publicStringgetPassword(){returnpassword;}publicvoidsetPhone(Stringphone){if(phone!null){intlenphone.length();if(len11){intl0;for(inti0;ilen;i){charchphone.charAt(i);if(ch0ch9){l;}else{System.out.println(手机号必须为数字符号);break;}}if(llen){this.phonephone;}}else{System.out.println(手机号长度必须为11位);}}}publicStringgetPhone(){returnphone;}publicvoidsetEmail(Stringemail){if(email!null){intlenemail.length();if(len6){System.out.println(邮箱至少6个字符);}intcount0;intposition-1;// 遍历整个邮箱字符串for(inti0;ilen;i){if(email.charAt(i)){count;// 每找到一个计数器1positioni;}}if(count1position!0position!len-1){this.emailemail;}else{System.out.println(邮箱必须包含一个符号,格式为账户名域名);return;}}}publicStringgetEmail(){returnemail;}publicvoidsetAddress(Stringaddress){if(address!null){intlenaddress.length();//检查地址里有没有 “” 字if(address.contains(省)address.contains(市)address.contains(区)){this.addressaddress;}else{System.out.println(地址必须包含 省/市/区);}}}publicStringgetAddress(){returnaddress;}publicvoidsetId(intid){if(id0){this.idid;}else{System.out.println(id必须为正整数);}}publicintgetId(){returnid;}publicvoidsetAge(intage){if(age0age150){this.ageage;}else{System.out.println(年龄不能为负数且在0-150之间);}}publicintgetAge(){returnage;}publicvoidshowInfo(){System.out.println(用户名userName密码password手机号phone邮箱email地址addressidid年龄age);}this .passwordpassword和 passwordpwdIn的区别this.password password解决 “参数名 属性名” 时的歧义是规范且通用的写法password pwdIn因参数名pwdIn和属性名password不同才无需this是特定场景的写法空参构造 逐个 set 赋值/带参构造 一次性赋值set 方法是校验核心构造方法只是调用 set不重复写校验两个测试只是用法不同校验完全一样pwdText和password的区别password 类里的私有属性存密码的地方pwdText 方法里的参数 / 临时变量临时传进来的密码password pwdText 把临时密码存进去int position -1i后才是从第一个字符开始查限制邮箱的格式必须为账户名域名包含且仅包含 1 个 且 不在开头也不在结尾-1 没找到、不存在、无效位置0 第一个字符的位置count 1 position ! 0 position ! len - 1为什么 id 不能用 null 和 length ()id 是 int 类型不是 String 字符串只有 字符串 String 才能用! null, .length(), .contains(), .charAt()int 是数字没有长度没有字符不可能为 null,只能用 !注意判断逻辑和if,else的位置

相关新闻