java中面向对象注意事项(总结一)-----自学JAVA(第五节)

来源:互联网 发布:python bytes 编辑:程序博客网 时间:2024/05/16 16:00

本文属于小编原创,请使用者标明出处:

一、类相关的概念

       1、类、方法、变量

              成员变量用于定义该类或者该类实例所包含的状态数据,

              方法则用于定义该类或该类实例的行为特征或功能实现,

              构造器用于构造该类实例。

             注:Java语言提供了一个功能:如果程序没有为一个类编写构造器,则系统会为该类提供一个默认的构造器,

                                                                  一旦程序为一个类提供了构造器,系统将不再为该类提供默认构造器。

              把使用static修饰的成员变量和方法称为类变量、类方法(也叫静态变量、静态方法),

              把不使用static修饰的成员变量和方法称为实例变量、实例方法;

             注:静态成员不能访问实例成员(方法同理),反之亦然。

              Java类作用:

              (1)定义变量

              (2)创建对象

              (3)调用类的类方法或访问类的类变量

            Java对象作用:

              (1)访问对象的实例变量

              (2)调用对象的方法

       2、对象、引用

           Person   p=new Person();   //Person是一个类

           分析上面代码:

                   p是一个引用,new Person()是一个对象;

                   在内存中p被存放在栈内存中,本身只存储了一个地址值(并为包含实际数据),地址值指向实际的对象;

                   new Person()被存放在堆内存中。

       3、对象的this引用

           this作为对象默认引用有两种情形:

                  构造器中引用该构造器正在初始化的对象;

                  在方法中引用调用该方法的对象。

           注:this可以代表任何对象,当this出现在某个方法体中时,它代码的对象是不确定的,但它类型是确定的,

                   它所代表的只能是当前类的实例,只有当这个方法被调用时,他所代表的对象才被确定下来,

                   static 修饰的方法中不能使用this,

                   this可以省略,如下情况除外:

                          如果方法中有个局部变量和成员变量同名,但程序有需要在方法中访问这个被覆盖的成员变量,则必须显示使用该this前缀。

        4、方法

             (1) 方法必须属于类和对象。

                       方法参数传递机制:

                             (1)基本类型的参数传递:传递的是实际参数的副本,参数本身不会受到影响;

                             (2)引用类型的参数传递:

                                                     采用的是值传递,即传递的是地址值,一处改变,其他地方跟踪变,实际改变的都是堆内存的数据。

                                                     虽然传递的是引用变量,但实际操作的还是堆内存中的对象。

             (2) Java中支持形参格式可变的方法,多个形参的参数值被当成数组传入。

                      格式:

                       public void test(int a , String ... books){     //该方法中形参个数可变。

                              //具体实现细节

                       }

                      注:个数可变的形参只能处于形参列表的最后,即,一个方法中最多只能有一个个数可变的形参。

            (3)递归方法

                      递归一定要向已知的方向递归。

            (4)方法重载

                     Java允许同一个类中定义多个同名方法,只要形参列表不同就行。

                     方法重载的要求:同一个类中方法名相同,参数列表不同。

       5、成员变量、局部变量

             类变量从该类的准备阶段起开始存在,直到系统完全销毁这个类,

             实例变量则从该类实例被创建起开始存在,直到系统完全销毁这个实例

             注:一个类在使用之前要经过类加载、类验证、类准备、类解析、类初始化等几个阶段。

                    一个类定义了类变量或者实例变量,系统就会在这个类的准备阶段或创建该类的实例时进行默认初始化

                   与成员变量不同的是:局部变量除了形参之外,都必须显示初始化。

                   Java允许局部变量和成员变量同名,如果方法里的局部变量和成员变量同名,局部变量会覆盖成员变量,如果需要在这个方法中引用被覆盖的成员变量,则可以使用this(实例变量)或类名(类变量)作为调用中来限定访问成员变量。

        5.1、成员变量的初始化和内存中的运行机制

                 当系统加载类或创建该类的实例时,系统自动为成员变量分配内存空间,并在分配内存空间后,自动为成员变量指定初始值。

                 内存中运行机制如下图所示:





上图分析:

                1、当程序执行PersonTest p1=new PersonTest();系统会加载这个类初始化这个类,在类的准备阶段,系统会为该类的类变量分配内存空间,并指定默认初始值

                      当PersonTest类初始化完成后,系统将在堆内存中为Person类创建一个类对象。

               2、执行代码PersonTest p2=new PersonTest();代码时,因为PersonTest已经存在于堆内存,所以不再需要对PersonTest类进行初始化。

                3、系统接着创建了一个PersonTest对象,并把这个PersonTest对象赋给P1变量,(PersonTest对象包含了名为name的实例变量),实例变量实例变量是在创建实例时分配内存空间并指定初始值。

                4、age类变量并不属于PersonTest对象,它属于类(所以PersonTest对象并没有保存age这个普通变量),所以创建PersonTest对象时并不需要为age变量分配内存(在内初始化阶段已经完成分配并初始化)。只为name实例变量分配了内存空间,并指定默认初始值。

               5、当程序执行p1.name="张三";时,将为p1的name实例变量赋值,堆内存中的name指向"张三",

                     name实例变量是属于单个PersonTest实例,因此修改第一个PersonTest对象的name实例变量时仅仅与该对象有关。

                     即,当执行p2.name="李四";时,第一个p1所指向的name并不会变化,p2.name="李四"是赋值另一个PersonTest对象中的name,在堆内存中单独分配了一块内存。

               6、不管是通过哪个实例来访问age类变量(其实建议类变量不要使用实例访问),本质还是通过PersonTest类来访问age类变量,他们访问的是同一快内存区。

         5.2、局部变量

               局部变量定义后,必须经过显示初始化后才能使用,系统不会为局部变量执行初始化。即,定义局部变量后,系统并未为这个变量分配内存空间,直到等到程序为这个变量赋初始值时,系统才会为局部变量分配内存,并将初始值保存在这快内存中。

              局部变量不属于任何类和实例,因此它总是保存所在方法的栈内存中,如果局部变量是基本类型变量,则直接把这个变量的值保存在该变量对应的内存中,如果局部变量是引用类型的变量,则这个变量存放的是地址,通过该地址引用到该变量时间引用的对象或数组。

              栈内存中的变量无须系统垃圾回收,往往随方法或代码块的运行结束而结束。






0 0
原创粉丝点击