Java基础之:OOP——封装
面向对象编程OOP(Object Oriented Programming)的三大特征之一:封装
封装就是把类的一部分属性或方法等"隐藏"起来,若外部想要访问必须要通过封装类提供的方法才能对数据进行操作。通过封装我们可以将一些重要的数据放在内部保护起来。
封装的优点
隐藏方法实现的细节。
对数据进行验证,保证数据的安全合理。(例: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{ }
说明:
Person类:
使用private修饰符封装了 name,age,salary,job属性。
通过setXxx() 与 getXxx() 的方法实现给属性赋值以及访问属性值的功能。
这里注意不一定方法名一定是set和get,但一定都是使用public修饰的。
可以看到在setAge和setSalary时,都做了if判断。通过这种方面实现了外部输入数据的过滤,对内部的数据进行了保护。避免出现不符合语义的数据进入,例如Age = 2000,salary = -10000。
在Person类中我们还使用了有参构造器与set方法结合使用。这样既可以便捷的使用构造器给对象赋值,又可以使用set方法的数据保护机制。
重写了toString方法,"@Override"这个符号现在不用考虑,之后会讲到。具体同String方法说明在Test类中体现。
Test类:
使用封装类的第一种方式,使用无参构造器,然后通过Person类提供的set方法为对象赋值。
数据输出时,也通过get方法去访问内部数据。可以看到这种方式实现时,代码量会比较大。
使用封装类的第二种方式,使用有参构造器,直接给对象赋值。
再使用toString方法输出对象的各属性信息。关于toString()方法的说明:
我们使用了一个测试类A来演示,在输出对象信息时会默认的调用toString方法。
若不对toString方法进行重写,输出的内容为:全类名 + 十六进制HashCode地址
由于我们在Person类中对toString方法进行了重写,所以会Person类的对象在输出时会按照我们定义的方式输出。
重写的概念会在之后的博客中给出。
案例总结
在对封装起来的属性写保护机制的时候,尽量在输入数据出错时附带一个默认值,这样可以保证整个程序不会出现"0"或"null"等无意义数据存在。
对象赋值可以灵活的选择set方法和有参构造器两种方式。
输出对象信息时,尽量使用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