Java中的封装

一、封装

封装是把过程和数据包装起来,对数据的访问只能通过已定义的接口

  1. 对数据(属性)的封装使用private
  2. 对过程(行为)的封装使用,给出访问权限为public的setter(给数据赋值,不需要返回值)方法和getter(获得赋值后的数据,需要返回值)方法

1.1方法封装

举个例子:对于一个Man这个类来说,name、age、wife都是私有属性,对于属性的封装使用“private”

public class Man {


    private String name;
    private int age;
    private String wife;

}
  • 那么对于这些属性来说,使用private封装属性的目的就是保护数据,不让人随意破坏,强制只能在本类中使用
  • 如果在其他类中想要通过其他类的对象来调用Man这个类的私有属性,就很不方便,因为设置成了private私有属性
  • 所以会在定义好private之后,在下面再进行public访问的权限的赋值setter和获取getter两种方法的封装

1.2行为(方法)封装

Man这个类对外界的类提供方法的封装,通过这些封装方法的调用,可以对Man这个类中的属性进行赋值set和获取get,设定姓名、年龄等,也可以获得姓名、年龄。

public class Man {


    //属性封装
    private String name;
    private int age;
    private String wife;


    //行为封装

    //其他类对私有属性name进行赋值,调用这个方法
   public void setName(String name){
       //this.name的name指得是类成员变量private String name;中的name
       // = name,即等号右边的name指的是(String name)中的形参name
       this.name = name;
   }

   //其他类获取私有属性name的值时,调用这个方法
   public String getName(){
       //这里的name指的就是上面private name
       return name;

   }

   //其他类对私有属性age进行赋值,调用这个方法
   public void setAge(int age){

       //this.age中的age指的是类成员变量private age,中的age\
       // = age,即等号右边的age指的是(int age)中的形参age
       this.age = age;
   }


}

1.3行为封装的快捷键

  • 先进行数据(属性)的封装。
public class Man {


    private String name;
    private int age;
    private String wife;

}
  • 点击右键,选择Generate

Java中的封装_第1张图片

  •  选择Getter and Setter

Java中的封装_第2张图片

  •  选择要进行封装的属性(按住Shift可多选),点击ok

Java中的封装_第3张图片

  •  生成的效果和之前是一样的
public class Man {


    //属性封装
    private String name;
    private int age;
    private String wife;

    
    //快捷键生成的方法封装
    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }
}
  • 这里没有进行private String wife;方法的封装,说明Man这个类不想让外界访问wife这个属性

1.3测试类访问封装数据

  • 对数据赋值时就调用Set方法,Set属性名(“实参“);
  • 想要获取到所赋值的实参时就用Get方法,Get属性名();
public class DemoApplication {

    public static void main(String[] args) {



      //利用new关键字创建一个对象man
        Man man = new Man();
        
        //调用封装的setName,属于有参无返的方法,故在括号中传入实参
        man.setName("张");
       
        //调用封装的getName,打印输出就调用这个方法
        System.out.println(man.getName());
        
        //调用封装的方法setAge,属于有参无返的情况,故在括号中传入实参
        man.setAge(1);

        //调用封装的方法getAge,打印输出就调用这个方法
        System.out.println(man.getAge());
        
    }
}

二、this关键字详解

2.1  this.属性名

作用:用来访问类成员变量,用于区分类成员变量和局部变量(方法体中的变量)

Java中的封装_第4张图片

例:现在有一个教师类,有三个public的类成员属性(实例变量)

public class Teacher {

    public String name;  //姓名
    public int age;  //年龄
    public double salary;  //工资
}

外界类想要方法这个类中的三个属性,直接访问且对这三个属性进行赋值肯定是做不到的,先需要构造器,

解决办法:为Teacher类添加一个构造方法,在方法中进行参数传递进行修改

  • 构造方法中 this.name = name;表示一个赋值语句
  • 等号左边this.name中this指的是指向本类的类成员变量
  • 等号左边this.name中的name指的是类成员变量public String name;中的name
  • 赋值语句 等号右边” = name “ 中的name指的是构造器括号中 "String name"传过来的参数 name
public class Teacher {

    public String name;  //姓名
    public int age;  //年龄
    public double salary;  //工资


    //出现有参构造时一定要定义无参构造
    public Teacher() {
    }

    //创建有参构造器,为上面三个属性赋值做准备
    public Teacher(String name, int age, double salary) {
        this.name = name;  //this.name  中的this指的是指向本类的成员变量, this.name中的name指的是本类中的public String name;中的name
        this.age = age;
        this.salary = salary;
    }
}

在测试类中,先new一个对象,因为new的过程中调用了构造器,所以在new的同时在括号中传入实参,代码示例如下:

public class DemoApplication {

    public static void main(String[] args) {

        //利用new关键字创建一个对象,同时传入实参
        Teacher teacher = new Teacher("甲",2,33.33);

        //打印输出结果为甲
        System.out.println(teacher.name);

        //打印结果输出为2
        System.out.println(teacher.age);

    }
}

打印输出的内容均是new过程中传入的实参。

总结:当一个类的类成员变量名和与访问该属性的方法参数名一致时,则需要用this关键字来访问类中的类成员变量,以区分类成员变量和方法中的参数。

Java中的封装_第5张图片

2.2  this.方法名

 作用:类中存在多个方法时,在某一个方法中通过 "this.方法" 调用另外一个方法,即让类中的一个方法,访问类中的另外一个方法或者访问类中的实例变量;

Java中的封装_第6张图片

例如:在Dog这个类中,

  • 定义一个jump()方法,方法中输出内容为“正在执行jump()方法” 
  • 定义一个run()方法,方法中调用 jump()方法,利用“this.方法名”的方式调用,且调用完成之后输出内容“正在执行run()方法”

代码示例如下:

public class Dog {

    //定义一个jump()方法
   public void jump() {

       System.out.println("正在执行jump方法");
   }

   //定义一个run()方法
   public void run() {
       //通过this调用jump()方法
       this.jump();
       System.out.println("正在执行run方法");

   }
}

在测试类中:

  • 通过new关键字创建一个对象(new的时候调用了默认的无参构造器)
  • 通过"对象.方法"的方式调用Dog类中的方法dog.run
  • 最终在控制台会按顺序打印输出:"正在执行jump方法","正在执行run方法",

代码示例如下:

public class DemoApplication {

    public static void main(String[] args) {

        //利用new关键字new一个Dog类的对象
        Dog dog = new Dog();

        //通过dog对象调用了Dog类中的run()方法;这个方法
        //run()方法中又通过this调用了本类方法jump()
        dog.run();

    }
}

注意:对于static修饰的方法而言,可以直接使用类来调用该方法,如果在ststic修饰的方法中使用this关键字,则这个关键字就会无法指向合适的对象,所以,static修饰的方法中不能用this引用,并且Java语法规定,静态成员不能直接访问非静态成员;

2.3  this()  访问构造器方法

作用:this() 用于访问本类的构造方法(构造器是类的一种特殊方法,方法名称和类名相同,没有返回值,括号中可以有参数,如果有参数就是有参构造方法)

  • 通过一个构造器方法1去调用另一个构造器方法2,实现代码复用
  • 构造器方法1和构造器方法2都在同一个类中
  • 语法:this(实参列表)
  • this(实参列表)的使用只能出现在第一个构造方法的第一行

Java中的封装_第7张图片

例:创建一个Student学生类,利用this(“实参列表”)给实例变量name赋值

  • 通过this("实参列表")调用类中的有参构造器对name进行赋值
  • this("实参列表“)必须放在第一个构造器的第一行

Student代码示例如下:

public class Student {

  public String name;

  //无参构造器
  public Student() {

      //通过this(“实参列表")调用类中的有参构造器对name进行赋值
      //this("有参构造")必须放在第一个构造器的第一行
      this("甲");
  }

  //有参构造器
  public Student(String name) {
      this.name = name;
  }

}

在测试类中。利用new关键字new一个对象出来后,打印输出name的值为甲

代码示例如下:

public class DemoApplication {

    public static void main(String[] args) {

        //利用new关键字new一个Student类的对象
        Student student = new Student();
        //控制台打印输出结果为甲
        System.out.println(student.name);


    }
}

三、在类的封装中加入抛出异常判断

定义一个Car类,封装其属性namecolor,

对于color属性来说,不能为red,否则爆红

对于name属性来说,不能传入null,否则报错

public class Car {


    private String name;
    private String color;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        /**
         * 判断 如果在启动项中赋值name为空 抛出异常
         */
        if ( name == null) {
            throw new IllegalArgumentException("invalid name");
        }
       
        this.name = name;
    }

    public String getColor() {
        return color;
    }

    public void setColor(String color) {
        /**
         * 判断 如果在启动项中赋值color为red 抛出异常
         */
         if ( name == null || name.isEmpty() ) {
            throw new IllegalArgumentException("invalid name");
        }
        this.color = color;
    }
}

在启动项中:

public class DemoApplication {

    public static void main(String[] args) {

        Car car = new Car();
        car.setColor("red");
        System.out.println("车子的颜色为--------------------"+car.getColor());
        car.setName(" ");
        System.out.println("车子的名字为---------------------"+car.getName());


    }
}

控制台报错如下:

Java中的封装_第8张图片

 

你可能感兴趣的:(Java基础,java)