编程日记:Java学习之路(八)

封装

一、Java中的引用

Java中的数据分为基本类型和引用类型,所以变量也可以分为基本变量和引用变量

定义的位置

  • 局部变量
  • 实力变量

定义的类型

  • 基本变量(保存的是值)
  • 引用变量(保存的是对象的内存地址)
import java.util.Date;

class Student {
        //引用变量
        String name;
        //基本类型
        int age;
        //引用类型
        Date birth;
        Student(String a,int b,Date c){
                name = a;
                age = b;
                birth = c;
        }
}
1 import java.util.Date;
2 
3 class Test {
4     public static void main(String[] args) {
5         Student stu = new Student("萧炎",16,new Date());
6     }
7 }

创建对象时JVM做了那些事?

虚拟机遇到一条new指令时,首先将去检查这个指令的参数是否能在常量池中定位到一个类的符号引用,并且检查这个符号引用表的类是否已被加载,解析和初始化过。如果没有,那必须先执行相应的类加载过程。在类加载检查通过后,接下来虚拟机将为新生对象分配内存。

 1 class Test {
 2     public static void main(String[] args) {
 3         Student stu = new Student("萧炎",16,new Date());
 4         System.out.println(stu.age);
 5         m1(stu.age);
 6         System.out.println(stu.age);
 7     }
 8     public static void m1(int age){
 9         age++;
10     }
11 }

这里值是不会发生变化的,因为stu存储的是对象的地址,而m1函数是无返回值的类型的函数,所以经过m1(stu.age)之后age的值是不会发生变化的

 1 class Test {
 2     public static void main(String[] args) {
 3         Student stu = new Student("萧炎",16,new Date());
 4         System.out.println(stu.birth);
 5         m2(stu.birth);
 6         System.out.println(stu.birth);
 7     }
 8     public static void m2(Date birth){
 9         birth.setTime(birth.getTime()+24*60*60*1000);
10     }
11 }

直接对地址值修改所以会改变

总结:在方法调用传参时

  • 基本类型变量传值
  • 引用类型变量传对象的内存地址(对个引用指向同一个对象)
  • 基本类型变量传参,如果在函数中改变参数的值,实参不会改变
  • 引用传参,如果在函数中形参没有指向其他对象,那么改变此对象内部状态的就是改变实参引用指向的对象的内部状态
  • String对象是不变对象,其内部状态不会发生改变,如需改变只能创建新的String对象

二、this关键字

作用1:

表示当前对象的引用

this.属性  //表示访问自己的属性

this.方法(参数)  //表示调用自己的方法

在一个对象的方法中,可以访问本对象的属性

如果方法中有同名的局部变量,则会优先访问局部变量。

此时如果要访问本对象的属性,则需要使用this引用

常见用法:

  • 当属性和局部变量命名冲突时,用来访问属性
  • 在方法中给本对象的属性赋值

作用2:

用在构造方法中,复用本类其他构造方法中的代码

this(参数) //执行相应构造方法中的代码

  • 只能用在构造方法中
  • 构造方法不能手动调用,只能使用this()方式避免冗余代码
  • 必须是构造方法中的第一行代码

常见用法:

  • 创建对象时给属性赋值

三、面向对象——封装

面向对象的三大特征:

封装——继承——多态

什么是封装?

任何对象都要有个明确的边界,由这个边界把对象分成对象的内部和对象的外部

边界应该对对象具有保护作用,使得:

  • 对象外部发生的变化不会影响到对象的内部
  • 对象内部发生的变化不会影响到对象的外部

边界的作用:把握对象的粒度

粒度过大:对象复杂,难以各司其职

粒度过小:对象多,系统复杂

边界的作用:数据隐藏

访问权限修饰符:

  • public:公开的
    • 修饰的属性或方法不受对象的边界的控制
    • 从对象的外部可以访问到
  • private:私有的属性公开时。对象的边界形同虚设,没有对对象的属性起到任何的保护作用。
    • 修饰的属性或方法无法穿过对象的边界
    • 只能从对象的内部访问到
  • 属性私有时,对象的边界可以对对象的属性起到保护作用,外界无法访问
  • 使用公开的方法间接地访问私有的属性,就相当于规定了访问的途径,访问的途径单一了,就可以控制访问的权限。

属性的分类:

  getter setter 举例
普通属性 公开 公开 姓名
只读属性 公开 不定义/私有 生日
只写属性 不定义/私有 公开 密码

获取属性的方法(getter):get属性名

设置属性的方法(setter):set属性名

 1 class Student {
 2         private String name;
 3 
 4         public String getName() {
 5                 return name;
 6         }
 7 
 8         public void setName(String name) {
 9                 this.name = name;
10         }
11 }

通常一个类的属性都是私有属性,只能通过公开的方法间接地访问这些属性

通过使用访问权限修饰符,可以灵活的控制某个属性的访问权限(只读/只读/读写),对象的属性全部在自己的控制之下,实现数据隐藏

方法也可以使用private修饰,这样的方法叫做私有方法

有些方法只希望能被同一个对象的其他方法调用,不希望其它对象调用,可以定义成私有方法

公开的方法指的是方法的声明公开,方法的实现隐藏

方法的调用者只需要关心方法的声明,在声明不变的情况下,即使改变方法的实现,也不会影响方法的调用者

封装的作用:

  • 让对象能够各司其职
  • 使对象之间为弱耦合性

迪米特法则:

一个对象应当对其他对象有尽可能少的了解

一个模块设计的好坏最重要的标志,就是该模块在多大程度上将它所有的实现细节隐藏起来,彻底的将它提供给外界的访问方式和内部实现分离

模块间仅通过模块提供的访问方式相互通信,而不关心对方内部的工作细节

尽量降低类的属性和方法的访问权限

 


Tip:到了不偷看的那天估计就释怀了吧


 

posted @ 2021-11-23 16:58  MachineHe  阅读(36)  评论(0)    收藏  举报