2020-12-02

Java基础之:OOP——封装

Java基础之:OOP——封装

面向对象编程OOP(Object Oriented Programming)的三大特征之一:封装

封装就是把类的一部分属性或方法等"隐藏"起来,若外部想要访问必须要通过封装类提供的方法才能对数据进行操作。通过封装我们可以将一些重要的数据放在内部保护起来。

封装的优点

  1. 隐藏方法实现的细节。

  2. 对数据进行验证,保证数据的安全合理。(例:Person类的age属性只能在1-120之间)

封装的实现

使用private访问修饰符 ,修饰属性或方法。对外界提供public修饰的方法对内部"隐藏"数据进行操作。

简单案例

Person类:


public class Person { public String name; private int age; private double salary; private String job;​  //构造器 + Set : 需要满足约束条件 public Person(String name, int age, double salary, String job) {  setName(name);  setAge(age);  setSalary(salary);  setJob(job); }  //重写toString方法  @Override public String toString() {  return "Person [name=" + name + ", age=" + age + ", salary=" + salary + ", job=" + job + "]"; }  public void setName(String name) {  if (name.length() >= 2 && name.length() <= 6) {   this.name = name;  } else {   System.out.println("姓名长度2-6,默认值小范");   this.name = "小范";  } }​ public void setAge(int age) {  if (age >= 1 && age <= 120) {   this.age = age;  } else {   System.out.println("年龄范围1-120,默认值18");   this.age = age;  } }​ public void setSalary(double salary) {  if (salary <= 1000000 && salary >= 1) {   this.salary = salary;  }else {   System.out.println("工资范围1-1000000,默认值10000");   this.salary = 10000;  } }​ public void setJob(String job) {  this.job = job; }​ public double getSalary() {  return salary; }  public double getAge() {  return age; }  public String getJob() {  return job; }}

Test类:

 

public class Test {​ public static void main(String[] args) {  //使用set get 方式  Person person = new Person();  person.setAge(120);  person.setJob("teacher");  person.setName("aaaaaaa");  person.setSalary(12000);  System.out.println("name: " + person.name);  System.out.println("age:" + person.getAge());  System.out.println("job:" + person.getJob());  System.out.println("salary:" + person.getSalary());    Person person = new Person("aaaaa", 8888,130000,"teacher");  //重写了toString方法之后  System.out.println(person.toString());    //没有重写toString方法 则会返回 全类名 + 十六进制HashCode地址  A a = new A();  System.out.println(a); //如果不写toString方法, 默认也是返回toString  System.out.println(a.toString()); //返回十六进制  System.out.println(a.hashCode()); //返回十进制 } }​class A{ }​

说明:

  1. Person类:

    1. 使用private修饰符封装了 name,age,salary,job属性。

    2. 通过setXxx() 与 getXxx() 的方法实现给属性赋值以及访问属性值的功能。

    3. 这里注意不一定方法名一定是set和get,但一定都是使用public修饰的。

    4. 可以看到在setAge和setSalary时,都做了if判断。通过这种方面实现了外部输入数据的过滤,对内部的数据进行了保护。避免出现不符合语义的数据进入,例如Age = 2000,salary = -10000。

    5. 在Person类中我们还使用了有参构造器与set方法结合使用。这样既可以便捷的使用构造器给对象赋值,又可以使用set方法的数据保护机制。

    6. 重写了toString方法,"@Override"这个符号现在不用考虑,之后会讲到。具体同String方法说明在Test类中体现。

  2. Test类:

    1. 使用封装类的第一种方式,使用无参构造器,然后通过Person类提供的set方法为对象赋值。

    2. 数据输出时,也通过get方法去访问内部数据。可以看到这种方式实现时,代码量会比较大。

    3. 使用封装类的第二种方式,使用有参构造器,直接给对象赋值。

    4. 再使用toString方法输出对象的各属性信息。关于toString()方法的说明:

      1. 我们使用了一个测试类A来演示,在输出对象信息时会默认的调用toString方法。

      2. 若不对toString方法进行重写,输出的内容为:全类名 + 十六进制HashCode地址

      3. 由于我们在Person类中对toString方法进行了重写,所以会Person类的对象在输出时会按照我们定义的方式输出。

      4. 重写的概念会在之后的博客中给出。

案例总结

  1. 在对封装起来的属性写保护机制的时候,尽量在输入数据出错时附带一个默认值,这样可以保证整个程序不会出现"0"或"null"等无意义数据存在。

  2. 对象赋值可以灵活的选择set方法和有参构造器两种方式。

  3. 输出对象信息时,尽量使用toString方法,可以使用 "System.out.println(对象名);"的方式,简洁明了。这里实际上是 "System.out.println(对象名.toString());" 只不过toString方法默认隐藏。

 

接下来我们看两个对于封装类的实际应用,为了代码方便阅读这里将各个类写在了一起,但在实际开发中应该保证一个类一个文件,所有类在同一个包下。

应用案例1

定义一个Person类 {name, age, job}, 初始化Person 对象数组,有3个person对象, 并按照 age 从 大到小进行排序,提示,使用冒泡排序.

public class Test { public static void main(String[] args) {  Person[] person = new Person[3];  // 初始化对象数组  person[0] = new Person("小范", 20, "老师");  person[1] = new Person("小黄", 18, "店长");  person[2] = new Person("小雨", 19, "舞蹈老师");​  // 遍历显示Person数组  for (int i = 0; i < person.length; i++) {   System.out.println(person[i]); // 默认就带有toString方法  }​  sort(person); // 排序  System.out.println("===========排序后=============");​  for (int i = 0; i < person.length; i++) {   System.out.println(person[i].toString());  } }​ // 冒泡排序 private static void sort(Person[] person) {  // 临时对象  // Person temp = new Person(); 自己的思路​  // 冒泡排序 自己的思路//  for (int i = 0; i < person.length - 1; i++) {//   for (int j = 0; j < person.length - 1 - i; j++) {//    if (person[j].getAge() > person[j + 1].getAge()) {//     // 使用 temp 对象 ,临时保存 , 将堆中的内容进行改变//     temp.setName(person[j].getName());//     temp.setJob(person[j].getJob());//     temp.setAge(person[j].getAge());//     //     person[j].setName(person[j + 1].getName());//     person[j].setJob(person[j + 1].getJob());//     person[j].setAge(person[j + 1].getAge());////     person[j + 1].setName(temp.getName());//     person[j + 1].setJob(temp.getJob());//     person[j + 1].setAge(temp.getAge());//    }//   }//  }​  // 冒泡 韩老师的思路  Person temp = null;​  // 冒泡排序 韩老师的思路  for (int i = 0; i < person.length - 1; i++) {   for (int j = 0; j < person.length - 1 - i; j++) {    if (person[j].getAge() > person[j + 1].getAge()) {     // 使用 temp 对象 ,临时保存 ,使用引用地址来进行交换     temp = person[j];     person[j] = person[j + 1];     person[j + 1] = temp;    }   }  } }​}​class Person { private String name; private int age; private String job;​ 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; }​ public String getJob() {  return job; }​ public void setJob(String job) { this.job = job; }​// 有参构造器   public Person(String name, int age, String job) {    this.name = name;    this.age = age;    this.job = job; }​// 无参构造器  public Person() { }​// 输出打印Person信息   public String toString() {    return "Person [name=" + name + ", age=" + age + ", job=" + job + "]"; }​}

 

应用案例2

计算圆的面积,圆柱的体积。

public class Test { public static void main(String[] args) {  Circle circle = new Circle();  Cylinder cylinder = new Cylinder();    circle.setRadius(2.5);  System.out.printf("圆半径:%.2f 圆面积:%.2f\n",circle.getRadius(),circle.findArea());    cylinder.setLength(3.1);  System.out.printf("圆柱高:%.2f 圆柱体积:%.2f\n",cylinder.getLength(),cylinder.findVolume(circle)); }}​/* * class Circle(圆) * -radius :double  Circle(): 构造方法,将radius 私有属性初始化为1 +setRadius(double radius) : void +getRadius(): double +findArea():double 计算圆的面积​ */class Circle{ private double radius;​ public Circle() {  //构造器  this.radius = 1; }​​ public double getRadius() {  return radius; }​ public void setRadius(double radius) {  this.radius = radius; }  public double findArea() {  return radius * radius * Math.PI; //Math.PI 返回 3.14..... }}​/* * class Cylinder(圆柱) * -length:double //高度 * Cylinder(): 构造方法,将length属性初始化为1 +setLength(double length):void +getLength():double +findVolume() :double 计算圆柱体积 * */class Cylinder{ private double length;  public Cylinder(double length) {  this.length = length; }​  public Cylinder() {  this(1); //调用上面的有参构造,将length初始化为1 }​​ public double getLength() {  return length; }​ public void setLength(double length) {  this.length = length; }  public double findVolume(Circle circle) { //使用Circle对象作为参数传递  return circle.findArea() * length; //直接使用findArea()方法 }}


 

 









原文转载:http://www.shaoqun.com/a/494628.html

拍怕:https://www.ikjzd.com/w/2205

skyee:https://www.ikjzd.com/w/290

米谷:https://www.ikjzd.com/w/1788


Java基础之:OOP——封装面向对象编程OOP(ObjectOrientedProgramming)的三大特征之一:封装封装就是把类的一部分属性或方法等"隐藏"起来,若外部想要访问必须要通过封装类提供的方法才能对数据进行操作。通过封装我们可以将一些重要的数据放在内部保护起来。封装的优点隐藏方法实现的细节。对数据进行验证,保证数据的安全合理。(例:Person类的age属性只能
斑马物联:斑马物联
ensogo:ensogo
口述:婚期将近我的初恋情人找上门:口述:婚期将近我的初恋情人找上门
国庆中秋杭州宋城特别活动 :国庆中秋杭州宋城特别活动
横岗哪里好玩?:横岗哪里好玩?

No comments:

Post a Comment