一、什么是封装呢?
封装是面向对象的三大特征之一。
隐藏对象的属性和实现细节,仅对外提供公共的访问方式。
①封装就是将面对对象的状态和行为看成是一个整体,将二者存放在一个独立的模块中,比如说类
②封装也是信息隐藏,把不需要让外界知道的信息隐藏起来,尽肯能隐藏对象功能实现细节,向外暴露方法,保证外界的安全访问,比如说方法
public static void SaveMan(int PhoneNumber,String name,int QQnumber,String Email,String wechant) { //我们在添加联系人时,需要传进的数据非常多而且很长,这就导致了参数列表的冗长 }
class LinkMan{ int PhoneNumber; String name; int QQnumber; String Email; String wechant; //这样我们就将联系人信息封装起来了,封装到了一个类里 }
二、为什么要封装呢?
1.我们先来看下边这段代码
public class FengZhuang { public static void main(String[] args) { Person p=new Person(); p.name="asa"; p.age=-17; //设置年龄的时候负数不合理,应该判断输入值是否正常 //这个值是可以通过圆点运算符.来进行存取修改的,设置的数据不安全 } } class Person{ String name; int age; }
那我们怎么解决上述问题呢?
class Person{ String name; //将年龄用权限修饰符设置为私有的,只能在本类中访问,外界无法访问。 //既然我们已经将年龄设置成私有的,外界无法访问,那我们怎么去设置它的值呢? //我们专门给age提供一个公共的方法,来对他进行访问,这就是Setter和Getter方法 private int age; public int getAge() { return age; } //我们可以通过set方法来对age进行访问,并且对传入的数据进行了筛选,这样就提高了数据的安全性 public void setAge(int age) { if(age<0) { System.out.println("年龄不能为负数"); return;//结束程序 }else { this.age = age; } } }
public class FengZhuang { public static void main(String[] args) { Person p=new Person(); p.setAge(-18); }
当我们输入一个负数年龄时,系统会给我们返回一个提示,提示我们不能是负数,但是我们并不知道它是怎么返回来的值,怎么去判断的这些细节,我们只知道结果。
①封装提高了代码的安全性。
②隐藏了实现细节,对外提供可以访问的方式。便于调用者的使用。
③提高了代码的复用性。
三、权限访问修饰符
封装让有些类看不到一些类里边具体做了什么,所以java提供了访问权限修饰符来一个类里边可以看到什么暴露什么,不可以看到什么暴露什么。
java中有四种访问权限修饰符,分别是private私有的,default不写,protected受保护的,public公共的
他们的访问权限如下
public |
protected |
default |
private |
|
同一类中 |
√ |
√ |
√ |
√ |
同一包中(子类与无关类) |
√ |
√ |
√ |
|
不同包的子类 |
√ |
√ |
|
|
不同包中的无关类 |
√ |
|
|
注意:private只能在本类中访问,离开本类后不能直接访问,在其他类中是可以访问但不能直接访问,比如上边代码中的set和get方法就是一种间接访问private修饰符的字段方法
一般字段都是使用private修饰符来修饰,达到隐藏和安全的要求。
2.那么什么情况该用什么修饰符呢?
从作用域来看,public能够使用所有的情况。 但是又不会真正全部都使用public,那么到底什么情况该用什么修饰符呢?
1. 属性通常使用private封装起来
2. 方法一般使用public用于被调用
3. 会被子类继承的方法,通常使用protected
再就是作用范围最小原则
简单说,能用private就用private,不行就放大一级,用package,再不行就用protected,最后用public。 这样就能把数据尽量的封装起来,没有必要露出来的,就不用露出来了
四、this关键字
现在有一辆自行车,小雨和小颖分别骑了一会这辆自行车,小雨说,这辆车我骑起来真重,那么当前“我”即这辆车的使用者就是小雨,小颖说,我骑起来还好,那么当前“我”即这辆车的使用者就是小颖。this就相当于我这个字,代表的是当前对象。
class Person{ String name; private int age; public int getAge() { return age; } public void setAge(int n) { if(n<0) { System.out.println("年龄不能为负数"); return; }else { //这里的n具体指什么呢? age = n; } } }
n指我们要传入的age,当我们把它换成age
class Person{ String name; private int age; public int getAge() { System.out.println(age); return age; } public void setAge(int age) { if(age<0) { System.out.println("年龄不能为负数"); System.out.println(age); return; }else { System.out.println(age); age = age; System.out.println(age); } } }
我们看到如上的输出结果,这表明get方法中的age获取到的是成员变量中的age,默认赋值0,这是因为程序遵循就近原则。
那怎么解决呢?
当成员变量和局部变量同名时,就可以用this关键字来区分,谁调用这个函数this就指的谁。
class Person{ String name; private int age; public int getAge() { System.out.println(age); return age; } public void setAge(int age) { if(age<0) { System.out.println("年龄不能为负数"); System.out.println(age); return;//结束程序 }else { System.out.println(age); this.age = age; System.out.println(age); } } }
public static void main(String[] args) { Person p=new Person(); p.setAge(18); System.out.println(p.getAge()); Person p2=new Person(); p2.setAge(20); System.out.println(p2.getAge()); }
程序输出结果如上图,当p对象调用时this就指的p这个对象,p2调用时this指的p2这个对象
那程序不是就近原则吗?为什这里的get方法获取到了我们传的这个值呢?
五、构造方法
1.什么是构造方法?它有什么作用?
构造方法是一种特殊的方法,它是一个与类同名且返回值类型为同名类类型的方法。对象的创建就是通过构造方法来完成
其功能主要是完成对象的初始化。当类实例化一个对象时会自动调用构造方法。构造方法和其他方法一样也可以重载。
class Person{ String name; int age; //无参构造,会默认就有,只是隐藏了我们看不见 public Person() { super(); } }
在Java中,任何变量在被使用前都必须先设置初值.Java提供了为类的成员变量赋初值的专门方法。
java中创建对象时会调用类的构造方法,如果我们不重写这个构造方法,它默认的是一个无参数的构造方法
2.实例化对象
当我们重写这个构造方法后再实例化对象
如果我们不传值,编译器会报错。
当我们也将无参构造写出来后,便可以不在实例化时就传值
内存图解
3.特殊性
8.自定义类中,如果不写构造方法,java系统会默认添加一个无参的构造方法。如果写了一个有参的构造方法,就一定要写无参构造方法。