Day08(private关键字(封装),类与对象的关系,对象的内存图)

一、类与对象的关系

1、如何使用Java语言描述现实世界的事物呢?

      举例:人

              五官,姓名,年龄,性别……

              吃饭、学习,说话……

            水杯:

                 颜色,材质,形状,容积……

                装水,泡茶……

                属性:用于描述事物的信息

                行为:用来描述事物用来做什么的

       我们学习编程语言,目的其实用来描述现实事物的世界,而我们现在所学的语言:java,现在就要开始学习如何使用Java来描述一个现实世界的事物,首先,我们知道java的最基本单位是:类

所以我们应该通过Java中的类去描述现实世界的事物,按照我们分析现实事物的角度出发得到一个与java中类的对应关系

       现实事物:

             属性:用于描述事物的信息

              行为:用来描述事物能够做什么的

       类:

          成员变量:用于描述事物的信息

           成员方法:用来描述事物 能够做什么

        类:是一组成员变量和成员方法的集合,可以把类看作是一个抽象的概念

         对象:是该类的具体表现,具体到一个个个体

    举例:

          事物:人

          属性:姓名,性别,年龄……

           行为:吃饭,睡觉,学习……

类:Person

          成员变量:name,gender,age

          成员方法:eat(),sleep(),study()

对象:是该类的具体表现,具体到一个个个体

          学生,老师,医生,程序员

【】定义一个学生类,完成类的成员(成员变量和成员方法)

    在一个java文件可以定义多个类,我们这里,就先定义基本的类和测试类,将来编译的时候,JVM会读取Java文件,有多少个class类,就编译生成多少个.class文件     

注意事项:一个Java文件中只能有一个类被public修饰,只要记住被public修饰的类规范是要与java文件名一致

     如何在测试类中使用学生类呢?

         创建该类的对象去使用

     如何创建对象呢?创建对象的格式是什么呢?

         类名 对象名称 = new 类名(...);

//这是一个学生类,类是java最基本的单位

public class Student{

    //成员变量

     //姓名

    String name;

     //性别

     String gender;

      //年龄

      int age;

      //定义成员方法

      //学习

      public void study(){

          System.out.println("我热爱学习大数据");

       }

        //吃饭

        public void eat(){

            System.out.println("学习饿了,吃会东西");

         }

          //睡觉

         public void sleep(){

             System.out.println("学习累了,睡一会觉");

          }

  }

   class StudentTest{

       public static void main(String[] args){

//         System.out.println("HelloWorld");

           //如果不创建对象能不能使用呢?(指的能否能访问到成员变量或者成员方法)

//          System.out.println(name);

             //创建一个学生对象才能使用

             Student s1 = new Student();

             //这样我们就创建出一个学生对象s1

             //如何通过对象访问成员变量呢?

             //访问格式: 对象名.成员变量名

             //访问 s1对象的姓名是什么

             //s1.name;

             //访问到的变量值不能直接使用,应该用一个变量接收或者直接使用输出

             System.out.println(s1.name);//null

             System.out.println(s1.gender);//null

             System.out.println(s1.age);//0

             //如何给成员变量赋值

             s1.name = "王宇";

             s1.gender = "男";

        //   s1.age = "明旺";//注意:赋值的时候注意数据类型

             s1.age = 18;

             System.out.println(s1.name);

             System.out.println(s1.gender);

             System.out.println(s1.age);

             //如何调用成员方法呢?

             //调用格式:对象名.成员方法名(……);

             s1.study();

             s1.eat();

             s1.sleep();

      }

}

2、创建一个对象的内存图

     Phone p1 = new Phone();

      //创建对象另外一种说法:实例化

      System.out.println(p1.brand);//null

      System.out.println(p1.price);//0

      System.out.println(p1.color);//null

     

       //给对象的成员变量进行赋值

       p1.brand = "华为";

       p1.price = 9999;

       p1.color = "曜石黑";

       

       System.out.println("手机的品牌是:"+p1.brand);

       System.out.println("手机的价格是:+p1.price");

       System.out.pricee("手机的颜色是:"+p1.color);

     

         //通过对象调用成员方法

         p1.call("杨老板");// 注意,调用对象的成员方法的时候,需要注意是否要传参!

         p1.sendMessage();

         p1.listenMusic();

   }       

Day08(private关键字(封装),类与对象的关系,对象的内存图)         

2、创建两个对象的内存图

      //定义一个手机类

      Phone1 p1 = new Phone1();

      //给手机对象p1成员变量赋值

     p1.brand = "小米";

     p1.price = 1999;

     p1.color = "白色";

     System.out.println(p1.brand+"---"+p1.price+"---"+p1.color);

     p1.call("雷军");

     p1.sendMessage();

     p1.listenMusic();

     //定义第二个手机对象

      Phone1 p2 = new Phone1 ();

      p2.brand = "苹果";

      p2.price = 4999;

      p2.color = "黑色";

      System.out.println(p2.brand+"--"+p2.price+"---"+p2.color);

      p2.call("乔布斯");

      p2.sendMessage();

      p2.listenMusic();

 

Day08(private关键字(封装),类与对象的关系,对象的内存图)

                                                                                                               

 3、创建三个对象的内存图

      //定义一个手机类

      Phone3 p1 = new Phone3();

      //给手机对象p1成员变量赋值

      p1.brand = "小米";

      p1.price = 1999;

      p1.color = "白色";

      System.out.println(p1.brand"---"+p1.price+"---"+p1.color);

      p1.call ("雷军");

      p1.sendMessage();

      p1.listenMusic();

      //定义第二个手机对象

      Phone3 p2 = new Phone3();

      p2.brand = "苹果手机";

      p2.price = 4999;

      p2.color = "黑色";

      System.out.println(p2.brand+"---"+p2.price+"---"+p2.color);

      p2.call("乔布斯");

      p2.sendMessage();

      p2.listenMusic();

      Phone3 p3 = p1;

      p3.brand = "华为";

      p3.price = 19999;

      p3.color = "蓝色";

      System.out.println(p1.brand+"---"+p1.price+"---"+p1.color);

Day08(private关键字(封装),类与对象的关系,对象的内存图) 

 4、匿名对象:就是没有名字对象

      匿名对象的使用场景:

             1、调用方法的时候,仅仅调用一次的时候,可以使用匿名对象

              注意:当多次调用的时候,不适合,每次new的时候都是一个新的匿名对象,会频繁的在堆内存中开辟空间,当匿名对象使用完毕之后,无法再使用第二次,就变成了一个垃圾(当栈中没有变量引用它的时候,判定是一个垃圾),等待被垃圾回收器回收

              2、当方法的参数类型是一个类的时候,可以使用匿名对象调用方法

class Phone4{

     public void show(){

         System.out.println("手机可以打电话");

     }

}

class PhoneDemo{

     public void function(Phone4 p){

        p.show();

      }

}

public class AnonymousDemo{

    public static void main(String[] args){

         //创建一个PhoneDemo对象

         PhoneDemo pd = new PhoneDemo();

         Phone4 phone = new Phone4();

         pd.function(phone);

         System.out.println("======================================");

         //当new完对象之后直接使用,没有用变量名接收的对象,称之为匿名对象

         new PhoneDemo().function(new Phone4());

         new PhoneDemo().function(new Phone4());

     }

}

 5、成员变量和局部变量

(1)成员变量与局部变量的区别:

                 1、在类中定义的位置不同

                      成员变量:类中但是在方法外

                      局部变量:定义在方法内部

                  2、在内存中的存储位置也不同

                        成员变量:在堆内存中

                        局部变量:在栈内存中

                   3、初始化值也不同

                          成员变量:系统会给予默认值

                          局部变量:没有系统给的默认值,必须在定义的时候赋值,亦或在方法中使用之前赋值,然后才能使用

                     4、生命周期不同

                           成员变量生命周期:随着对象的创建而创建,随着对象的消失而消失

                           局部变量的生命周期:随着方法的调用而创建,随着方法的调用完毕而消失

(2)注意事项:

         1、局部变量的名字可以和成员变量的名字一样,在方法中使用的时候,采用就近原则,方法中使用的变量,会先在方法内部查找,如果方法内部没有,去成员变量中查找

         2、方法与方法之间里面的局部变量不能互相调用

class BianLiang{

    String name;

    int age;

    public void show(int n){

        n = 10;

        int a = 20;

//      int b;

//      System.out.println(b);

         System.out.println(n);

          System.out.println(a);

         String name = "王宇";

         System.out.println(name);

     }

//public void show2(){

//    System.out.println(a);

     }

}

public class BianLiangDemo{

     public static void main(String[] args){

         //成员变量的使用,需要创建对象(最起码这里要创建对象才能使用)

         BianLiang b1 = new BianLiang();

         b1.name = "明旺";

         System.out.println(b1.name);

         b1.show(100);

    }

}

二、private关键字(封装)

1、我们在定义一个学生类并使用的时候,发现了一个问题:

       通过对象给成员变量赋值的时候,可以赋值一些非法的数据,这样是不合理不符合现实生活的,我们应该在赋值之前,做一次判断,数据校验,也就是对即将要赋值的数据做判断

        问题又来了,我们应该在哪里定义这个这个判断逻辑呢?

         StudengtDemo2是一个测试类,一般情况下测试类负责创建对象并使用对象的地方,在这里定义判断逻辑是不合适的

        所以我们这里应该定义在Student3类中

        又因为我们在定义成员变量的时候无法加入逻辑判断,所以我们在成员方法中定义。因为做数据判断的时候,加的是一些逻辑判断语句,肯定不是只有一条。我们应该在Student3类中体重一个方法来数据校验。

        按照我们的想法,在类中提供了一个数值校验的方法,如果符合就成功赋值,反之则不赋值,但是,谁规定了我定义了方法就一定会被使用呢,如果我还是用之前的获取成员变量的方式进行赋值,问题依旧存在,那么我们给出的方法意义就不是很大了。

        实际上,我们应该定义了一个方法后,让调用必须使用我们的方法进行赋值,并且不能让调用者直接获取到我们的成员变量。

       怎么样去强制要求不直接获取成员变量呢?

       针对这样的情况,Java就提供了一个关键字:private

       private:私有的

       其实说到现在,就是为了引出一个思想:封装

       封装:其实就是隐藏对象的属性和相关的实现细节,仅仅对外提供公共的访问方式

class Student3{

   //定义成员变量

   String name;

   private int age;

   public void setAge(int a){

        if(a< 0 || a>200){

            System.out.println("您要传入的年龄数据有误,请重新赋值");

         }else {

              age = a;

          }

     } 

     //定义一个输出所有的成员变量

      public void show() {

          System.out.println("姓名:"+ name);

          System.out.println("年龄:"+ age);

       }

}

public class StudentDemo2{

      public static void main(String[] args){

          //创建一个学生对象

          Student3 s = new Student3();

          s.show();

          //给对象的成员变量赋值

          s.name = "王宇";

    //    s.age = 18;

    //     s.age = 10000;

    //     s.setAge(10000);

    //age在com.shujia.wyh.day08.Student3中是private访问控制

     //    s.age = 10000;//由于我们在Student3类中name前面加了一个private关键字,不可以直接使用获取到成员变量,要想赋值就必须使用我们提供的数据校验赋值方法

            s.setAge(10000);

            s.show();

      }

}

2、规范定义一个类的标准版本1.0

     1、将成员变量使用private修饰

     2、提供公共的getXxx()和setXxx()

     3、提供一个方法打印所有的成员变量值(先自己定义,后面我们会学习新的方法替代)

public class Teacher{

    //定义成员变量

    private String name;

    private int age;

    //提供公共的getXxx()和setXxx()方法

     public void setName(String s){

           name = s;

      }

      public String getName(){

           return name;

      }

      public void setAge(int a){

            age = a;

       }

       public int getAge(){

            return age;

       }

       //提供一个方法打印所有的成员变量值

        public void show(){

              System.out.println("姓名:"+ name+ ",年龄:"+age);

        }

}

class TeacherTest{

      public static void main(String[] args){

          //创建一个老师对象

          Teacher t1 = new Teacher();

          //使用成员变量

          //不能直接获取,因为他们都是被private修饰了

     //     System.out.println(t1.name+"---"+ t1.age);

     //   通过公共的方法来获取成员变量

             System.out.println(t1.getName()+"---" +t1.getAge());

     //     给成员变量赋值

            t1.setName("刘志城");

            t1.setAge(18);

            System.out.println(t1.getName()+ "---" + t1getAge());

            t1.show();

      }

}

上一篇:Day08_异常机制


下一篇:day08数据库多表查询