Java三大特性:封装,继承,多态。
请记住这三个关键词,只要你不放弃学Java,这三个关键字就会一直伴随你整个Java学习过程。今天我就先讲讲封装,继承和多态可以查看我其余两篇文章。
Java是一个面向对象语言,这个是基础也是核心,如果你不知道这个概念,那么请点击右上角的×,出门右转。
什么是封装?对调用者隐藏内部实现细节。
这句很抽象,初学Java的你们可能根本不懂什么是隐藏内部细节,我们用一个简单的例子来讲解一下。
Person是一个简单的类的,用来测试的。
public class Person {
public String lastName;
public String firstName;
public int age;
public Person() {}
public Person(String lastName, String firstName, int age) {
this.lastName = lastName;
this.firstName = firstName;
this.age = age;
}
public void displayPerson() {
System.out.print("Last name:" + lastName);
System.out.print(",First name:" + firstName);
System.out.println(",age:" + age);
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
}
我们来一组代码对比
public static void main(String[] args) {
//直接赋值
Person person1 = new Person();
person1.firstName="first 1";
person1.lastName = "last 1";
person1.age = 20;
//采用封装的赋值
Person person2 = new Person();
person2.setFirstName("first 2");
person2.setLastName("last 2");
person2.setAge(30);
}
感觉好像没有多大的优势???代码行数好像没有变少一点,上下的感觉都差不多的???
这种封装确实没有多大的优势,个别大佬认为get和set方法都不能算封装的。
现在问题增加了,一个人的年龄不能太大,也不能太小吧甚至为负数吧,假如有人告诉你,自己年龄为-10岁,你第一反应肯定是对方脑子有问题。这样的问题逻辑换到代码里面,肯定也是同样成立的。
修改过后的直接赋值代码
if (age > 0 && age < 150) {
person.age = age;
}
没有毛病吧,对赋值年龄进行检测,然后进行赋值。好像貌似没有毛病。如果你只实例化了一个两个Person对象好像也没有多大问题,一个一个手动修改就是了,万一你实例化了几十个Person对象对象,那你工作量就很大了。那你说没有问题,几十个我还是可以手动修改,那几百个呢?几千个呢?你说好,没问题,我手动修改。等你修改完了,万一需求又改了?比如年龄上限修改成200了?你还要一个一个的手动修改吗?
现在上封装的办法
// 修改set方法,一般不推荐修改get和set方法,这里只是为了举例方便
public void setAge(int age) {
if (age > 0 && age < 150) {
this.age = age;
} else {
// 错误处理
}
}
person.setAge(age);
简单的修改了一下set方法,调用方式依旧不变,是不是突然发现简单很多了。即使你实例化了一堆对象,我们需要维护的只有Person类的。
好像我这样讲已经偏离的封装的本意,我觉得get和set方法只是为了符合封装的规范强行加上去的。现在我们修改一下Person类,多了一个年龄增长的方法growing();要求可以增长一岁。
public void growing() {
// age++;
// ++age;
// age = age + 1;
age += 1;
}
我们可以有多种多样的实现方式,对于Person的调用者来说,他是不关心你是怎么实现这个年龄增长的,他只关心调用结果,也就是age增加了1。当然这是一个比较简单的例子,封装的代码也比较少的,当你逻辑结构复杂了,代码多了封装的优越性就体现出来了。
我觉得刚开始你们和我有一样的疑惑,感觉好像封装没有多大的用处,因为封装的本质就是对调用者隐藏内部实现的细节,初学者可能写的代码太少,不懂什么是隐藏细节。我举个简单的例子
System.out.println("Hello World!")
我相信这行代码你们应该敲过吧,这也是一种封装的体现。我们并不关心这行代码是如何实现在控制台打印输出的,但是我们知道我们调用过后会在控制台打印输出相应的字符串。
总结:封装这个概念对初学者可能不友好,因为感觉和函数调用差不多的,但是随着学习的推进,会发现这种思想是很有用的,毕竟这些概念都是一些大佬提出的,是他们对于经验的总结。我觉得初期学这些东西更多的意义在于规范,规范自己的代码,为将来的发展铺平道路。