面向对象编程
说到类和对象,就一定要先说明面向对象究竟是什么。
- 面向过程编程
在早期,人们解决问题都是将问题拆解,将一个大问题分解为若干步骤,然后逐步解决。其中最经典的例子则是:如何将大象装进冰箱?显然,将大象装进冰箱只需三步:1. 将冰箱门打开;2. 将大象装入冰箱;3. 把冰箱门关上。这也许有点滑稽,但是它也确确实实的反映出面向过程这种编程的思想:自顶向下,逐步求精。 - 面向对象编程
还是以“将大象装入冰箱”为例,如果使用面向对象的思想,我们只需要知道完成这件事只需要冰箱和大象即可。至于大象如何走进冰箱、冰箱如何开关门,则是大象和冰箱的问题了。 - 二者谁更好
面向过程和面向对象都是我们解决问题的一种方式,这并不是一个非黑即白的问题,并非所有的问题都必须用面向对象的方法来解决。
类和对象
类
类是面向对象的主体,它描述了一类事物的特征,比如人有五官,会走会跑。一切事物我们都可以看作对象。正如“将大象装进冰箱”这个例子,解析后我们可以得到两个类——大象和冰箱。
在得到大象和冰箱这两个类后,我们继续深究如何将大象装进冰箱。显然,大象要会“走路”、冰箱要会“开关门”,才能完成这件事。我们以代码的方式展现:
// 大象
public class Elephant {
public void walk() {
System.out.println("我是大象,我会用四条腿走路。");
}
// 冰箱
public class Refrigerator {
public void open() {
System.out.println("我是冰箱,我会开门。");
}
public void close() {
System.out.println("我是冰箱,我会关门。");
}
对象
在完成了对一类事物的描述——类的创建后,我们需要将类实例化,实例化的结果我们称为对象。
Elephant e1 = new Elephant(); // e1是对象
Refrigerator r1 = new Refrigerator(): // r1是对象
r1.open(); // 打开冰箱门
e1.walk(); // 大象走进冰箱
r1.close(); // 关闭冰箱门
方法和属性
在上面的例子中,我们说明了大象和冰箱的作用,这些我们称之为方法;我们还可以通过增加一些变量来具体描述这个类。
// 大象
public class Elephant {
private double weight; // 属性,大象的体重
public double ivory; // 属性,象牙的长度
public double nose; // 属性,鼻子的长度
private void eat(String something) { // 方法,大象可以吃。。。
System.out.println("我想吃" + something);
}
public void walk() { // 方法,大象会走路
System.out.println("我是大象,我会用四条腿走路。");
}
// 冰箱
public class Refrigerator {
public int longth; // 冰箱的长
public int width; // 冰箱的宽
public int high; // 冰箱的高
public double Refrigeration(double celsius) { // 制冷
System.out.println("你想调到几度?" + celsius);
return celsius;
}
public void open() {
System.out.println("我是冰箱,我会开门。"); // 开门
}
public void close() {
System.out.println("我是冰箱,我会关门。"); // 关门
}
面向对象的三大特性——封装、继承、多态
封装
顾名思义,即隐藏对象的属性和实现细节,仅对外公开接口。这会让类的内部保证安全。
继承
以大象为例,我们知道,并非所有的大象都有象牙(已经有大象逆进化失去象牙),而且随着人类对大象的探索,得知大象是通过次声波交流,此时我们要去对大象这个类进行修改吗?答案是不需要!我们可以通过继承来减少代码的复杂度,继承后的类拥有父类的所有非私有属性和方法。不过需要特别注意的是,Java只支持单继承。
public class ElephantFather {
public int weight;
private int nose;
public void walk() {
System.out.println("我会走路");
}
}
public class ElephantSon extends ElephantFather {
public void ivory() {
System.out.println("爸爸没有象牙,我进化出象牙啦);
}
}
public class Test {
public static void main(String[] args) {
ElephantSon e1 = new ElephantSon();
e1.weight = 100;
System.out.println("爸爸有体重,我也有" + e1.weight);
e1.walk(); // 子类可以使用父类的方法
e1.ivory(); // 子类拥有自己独特的方法
// e1.nose = 10; 这段代码编译不通过
}
}
多态
仍然以大象为例,成年的大象走路很稳重,刚出生的小象走起路来则跌跌撞撞,如何使用同一个方法来描述这两种情况呢?
class ElephantFather {
public void work() {
System.out.println("我是爸爸,我走路很稳");
}
}
class ElephantSon extends ElephantFather {
public void work() {
System.out.println("我是儿子,我走路有点晃");
}
}
public class Test{
public static void main(String[] args) {
ElephantSon e1 = new ElephantSon();
e1.work(); // 我是儿子,我走路有点晃;显然,我们使用了同名的方法实现了不同的功能
}
}