第7天 构造函数、this关键字、静态修饰符static

来源:互联网 发布:华为手机免费网络硬盘 编辑:程序博客网 时间:2024/06/01 08:56

1. 复习

对象:真实存在的唯一的事物。

类: 同一种类型的事物公共属性与公共行为的抽取。

java面向对象语言:

核心思想: 找适合的对象做适合的事情.

找对象的方式:

    方式一: sun已经定义好了很多了类,我们只需要认识这些类即可创建对象使用。

    方式二: 我们需要自定义类,通过自定义类创建对象。

在整理笔记的过程中对自己有疑问的概念使用代码验证或者推翻它。

自定义类三步骤:

    1. 自定义一个类。

         class 类{

           事物 的公共属性使用成员 变量描述

           事物的公共行为使用函数描述。

         }

    2. 可以通过类创建对象。

    3. 访问(设置)对象的属性或者调用对象的方法。

成员变量与局部变量 的区别:

    1. 自定义的位置区别:

           1. 成员变量是定义在方法之外,类之内的变量。

           2. 局部变量是声明在方法之内的变量。

    2. 作用上的区别:

           1. 成员变量的作用描述一类事物的属性。

           2. 局部变量的作用是提供一个变量给方法内部使用的。

    3. 生命周期的区别;

           1. 成员变量随着对象的创建而存在,随着对象的消失而消失。

           2. 局部变量是调用到了对应的方法执行 到了创建该变量的语句时存在,一旦出了自己的作用域马上从内存中消失。

    4. 初始值的区别:

           1. 成员变量是有默认的初始值的。

           2. 局部变量是没有默认的初始值的,必须要先初始化才能使用。

匿名对象: 没有引用类型变量指向的对象就称作为匿名对象。

匿名对象要注意的细节:

       1. 一般不会给匿名对象的属性赋值,因为永远都没法获取到。

       2. 两个匿名对象永远都不可能是同一个对象。

匿名对象好处:简化书写。

匿名对象的应用场景:

    1. 如果调用一个对象的方法一次时,然后这个对象就不再使用,那么这时候可以使用匿名对象。

    2. 可以作为实参调用一个函数。

封装:

封装的步骤:

    1. 使用private修饰需要被封装的属性.

    2. 根据需要提供get或者set方法设置以及获取属性。

封装的好处:

    1. 提高了数据的安全性。

    2. 操作简单。

    3. 隐藏了实现。

注意:一般实体类的属性我们都会封装起来。 

2.构造函数

1)构造函数的作用

给对应的对象进行初始化

2)构造函数定义的格式

修饰符 函数名(形式参数){

函数体...

}

3)构造函数要注意的细节

ü  构造函数 是没有返回值类型的。

ü  构造函数的函数名必须要与类名一致。

ü  构造函数并不是由我们手动调用的,而是在创建对应的对象时,jvm就会主动调用到对应的构造函数。

ü  如果一个类没有显式的写上一个构造方法时,那么java编译器会为该类添加一个无参的构造函数的。

ü  如果一个类已经显式的写上一个构造方法时,那么java编译器则 不会再为该类添加 一个无参 的构造方法。

ü  构造函数是 可以在一个类中以函数重载 的形式存在多个 的。

4)`构造函数代码示例

<span style="font-family:Microsoft YaHei;font-size:14px;">class Baby{    int id; //身份证    String  name;  //名字    //构造函数    public  Baby(int i ,String n){       id  = i;       name = n;       System.out.println("baby的属性初始化完毕!!");    }    //无参 的构造函数    public Baby(){       System.out.println("无参的构造函数被调用了..");    }    //哭    public void cry(){       System.out.println(name+"哇哇哭...");    }  }class Demo2{    public static void main(String[] args)    {         //创建一个baby对象       Baby b1 = newBaby(110,"狗娃"); //婴儿诞生   白户       System.out.println("编号:"+ b1.id +" 姓名:"+ b1.name);       b1.cry();       b1.cry();    }}</span>

5)构造函数的疑问

创建对象时,jvm就会调用到对应的构造方法,那么我们以前没有学构造方法,那么

以前创建对象时,jvm是否 也会调用构造方法呢?如果有?构造方法从何而来呢?

会调用, java编译器在编译的 时候给加上去的。

jdk提供了一个java开发工具(javap.exe)给我们进行反编译的。

javap 反编译工具的使用格式:javap -c -l -private 类名

6)构造函数与普通函数的区别

1. 返回值类型的区别:

ü  构造函数是没有返回值类型 的,

ü  普通函数是有返回值类型的,即使函数没有返回值,返回值类型也要写上void。

2. 函数名的区别:

ü  构造函数的函数名必须要与类名一致,

ü  普通函数的函数名只要符合标识符的命名规则即可。

3. 调用方式的区别:

ü  构造函数是 在创建对象的时候由jvm调用的。

ü  普通函数是由我们使用对象调用的,一个对象可以对象多次普通 的函数

4. 作用上的区别:

ü  构造函数 的作用用于初始化一个对象。

ü  普通函数是用于描述一类事物的公共行为的。

3.构造代码块(1)

1)构造代码块的作用:给对象进行统一的初始化。

2)构造函数的作用: 给对应的对象进行初始化。

3)构造代码块的格式

    {

        构造代码块

    }

 

注意: 构造代码块的大括号必须位于成员位置上。

4)构造代码块的类别:

    1. 构造代码块。

    2. 局部代码块.  大括号位于方法之内。 作用:缩短局部 变量 的生命周期,节省一点点内存。

    3. 静态代码块 static

{

       //System.out.println("构造代码块的代码执行了......");  

}

4.构造代码块(2)

构造 代码块要注意的事项:

    1. java编译器编译一个java源文件的时候,会把成员变量的声明语句提前至一个类的最前端。

    2. 成员变量的初始化工作其实都在在构造函数中执行的。

    3. 一旦经过java编译器编译后,那么构造代码块的代码块就会被移动构造函数中执行,是在构造函数之前执行的,构造函数的中代码是最后执行的。

    4. 成员变量的显示初始化与构造代码块 的代码是按照当前代码的顺序执行的。

<span style="font-family:Microsoft YaHei;font-size:14px;">class Demo5{    //构造函数    public Demo5(){   //构造函数       i = 300000000;       }    //构造代码块   //构造代码块的初始化    {       i = 200000000;    }    int i = 100000000;   //成员变量的显初始化    public static void main(String[] args)    {       Demo5 d = new Demo5();       System.out.println("i = "+d.i); //    双、吴、刘 :2000   :    }}</span>

5.this关键字

1)this关键字

this关键字代表是对象的引用。也就是this在指向一个对象,所指向的对象就是调用该函数的对象引用。

2)this关键字的作用

ü  如果存在同名成员变量与局部变量时,在方法内部默认是访问局部变量的数据,可以通过this关键字指定访问成员变量的数据。

ü  在一个构造函数中可以调用另外一个构造函数初始化对象。

3)this关键字调用其他的构造函数要注意的事项

ü  this关键字调用其他的构造函数时,this关键字必须要位于构造函数中的第一个语句。

ü  this关键字在构造函数中不能出现相互调用 的情况,因为是一个死循环。

4)this关键字要注意的事项

ü  存在同名的成员变量与局部变量时,在方法的内部访问的是局部变量(java 采取的是“就近原则”的机制访问的。)

ü  如果在一个方法中访问了一个变量,该变量只存在成员变量的情况下,那么java编译器会在该变量的 前面添加this关键字。

5)this关键字代码实例

<span style="font-family:Microsoft YaHei;font-size:14px;">class Animal{    String name ;  //成员变量    String color;    public Animal(String n , String c){       name = n;       color = c;    }    //this关键字代表了所属函数的调用者对象    public void eat(){       //System.out.println("this:"+ this);       String name = "老鼠"; //局部变量       System.out.println(name+"在吃..."); //需求: 就要目前的name是成员变量的name.          }}class Demo6{    public static void main(String[] args)    {       Animal dog = new Animal("狗","白色");  //现在在内存中存在两份name数据。       Animal cat = new Animal("猫","黑色");       cat.eat();    }}</span>

6.this关键字调用本类的构造方法

<span style="font-family:Microsoft YaHei;font-size:14px;">classStudent{    int id; //身份证    String name; //名字    //目前情况:存在同名 的成员 变量与局部变量,在方法内部默认是使用局部变量的。    public Student(int id,String name){  //一个函数的形式参数也是属于局部变量。       this(name); //调用了本类的一个参数的构造方法       //this(); //调用了本类无参的 构造方法。       this.id = id; // this.id = id 局部变量的id给成员变量的id赋值       System.out.println("两个参数的构造方法被调用了...");    }    public Student(){       System.out.println("无参的构造方法被调用了...");    }    public Student(String name){       this.name = name;       System.out.println("一个参数的构造方法被调用了...");    }}classDemo7{    public static void main(String[] args)    {       Student s = new Student(110,"铁蛋");       System.out.println("编号:"+ s.id+" 名字:" + s.name);/*       Student s2 = new Student("金胖子");       System.out.println("名字:" + s2.name);    */    }}</span>

总结:实际工作中,存在着构造函数之间的相互调用,但是构造函数不是普通的成员函数,不能通过函数名自己接调用

所以sun公司提供this关键字。

this是什么

1:在构造函数中打印this

2:创建对象,打印对象名p

3:this和p是一样的都是内存地址值。

4:this代表所在函数所属对象的引用。

7.this关键字的练习

需求: 使用java定义一个人类,人具备 id、name 、 age三个属性,还具备一个比较年龄的方法。

要求: 必须 要 写上构造函数,构造函数也必须要使用上this关键字。

<span style="font-family:Microsoft YaHei;font-size:14px;">class Person{    int id; //编号    String name; //姓名    int age;  //年龄    //构造函数    public Person(int id,String name ,int age){       this.id  = id;       this.name = name;       this.age = age;    }    //比较年龄的方法    public void compareAge(Person p2){       if(this.age>p2.age){           System.out.println(this.name+"大!");       }else if(this.age<p2.age){           System.out.println(p2.name+"大!");       }else{           System.out.println("同龄");       }    }}class Demo8{    public static void main(String[] args)    {       Person p1 = new Person(110,"狗娃",17);       Person p2 = new Person(119,"铁蛋",9);       p1.compareAge(p1);    }}</span>

8.static修饰成员变量

static(静态\修饰符)

    1. static修饰成员变量 :如果有数据需要被共享给所有对象使用时,那么就可以使用static修饰。

       静态成员变量的访问方式:

              方式1: 可以使用对象进行访问。

                  格式: 对象.变量名。

              方式二: 可以使用类名进行访问。

                  格式: 类名.变量名;

           注意:

              1. 非静态的成员变量只能使用对象进行访问,不能使用类名进行访问。

              2. 千万不要为了方便访问数据而使用static修饰成员变量,只有成员变量的数据是真正需要被共享的时候

              才使用static修饰。

       static修饰成员变量的应用场景: 如果一个数据需要被所有对象共享使用的时候,这时候即可好实用static修饰。

    2. static修饰成员函数:

<span style="font-family:Microsoft YaHei;font-size:14px;">classStudent2{    static Stringname;  //非静态成员变量    static String  country = "中国";    //静态的成员变量    public Student2(String name){       this.name = name;    }}classDemo10 {    public static void main(String[] args)    {       Student2 s1 = new Student2("狗娃");       Student2 s2 = new Student2("狗剩");       //System.out.println("国籍:"+Student.country);       System.out.println("名字:"+ s1.name);       System.out.println("名字:"+ s2.name);    }}</span>

9.static修饰成员变量的应用场景

需求: 统计一个类被使用了多少次创建对象,该类对外显示被创建的次数。

<span style="font-family:Microsoft YaHei;font-size:14px;">class Emp{    //非静态的成员变量。    static int count = 0;    //计数器    String name;    //构造代码块    {       count++;    }    public Emp(String name){       this.name = name;     }    public Emp(){  //每创建一个对象的时候都会执行这里 的代码    }    public void showCount(){       System.out.println("创建了"+ count+"个对象");    }}class Demo11{    public static void main(String[] args)    {       Emp e1 = new Emp();       Emp e2 = new Emp();       Emp e3 =new Emp();       e3.showCount();    }}</span>


 

0 0