面向对象面向对象思想有三个基本特性:封装性、继承性和多态性。
封装性
在现实世界中封装的例子到处都是。例如:一台计算机内部极其复杂,有主板、 CPU、硬盘和内存,而一般用户不需要了解它的内部细节,不需要知道主板的型号、 CPU 主频、硬盘和内存的大小,于是计算机制造商将用机箱把计算机封装起来,对外提供了一些接口,如鼠标、键盘和显示器等,这样当用户使用计算机就变非常方便。那么,面向对象的封装与真实世界的目的是一样的。封装能够使外部访问者不能随意存取对象的内部数据,隐藏了对象的内部细节,只保留有限的对外接口。外部访问者不用关心对象的内部细节,使得操作对象变得简单。
继承性
在现实世界中继承也是无处不在。例如:轮船与客轮之间的关系,客轮是一种特殊轮船,拥有轮船的全部特征和行为,即数据和操作。在面向对象中轮船是一般类,客轮是特殊类,特殊类拥有一般类的全部数据和操作,称为特殊类继承一般类。在 Java 语言中一般类称为“父类”,特殊类称为“子类”。
多态性
多态性是指在父类中成员变量和成员方法被子类继承之后,可以具有不同的状态或表现行为。
类声明
Java 语言中一个类的实现包括:类声明和类体。类声明语法格式如下。
[public][abstract|final]class className [extends superclassName][implements interfaceNameList] {
//类体
}
其中,class是声明类的关键字,className 是自定义的类名;class 前面的修饰符public、abstract、final 用来声明类, 它们可以省略,它们的具体用法后面章节会详细介绍;superclassName为父类名,可以省略,如果省略则该类继承 Object 类,Object 类所有类的根类,所有类都直接或间接继承 Object;interfaceNameList 是该类实现的接口列表,可以省略, 接口列表中的多个接口之间用逗号分隔。
括号([])部分表示可以省略; 竖线(|)表示“或关系” ,例如abstract|final,说明可以使用abstract或final关键字,两个关键字不能同时出现。
声明动物(Animal)类代码如下:
// Animal.java
public class Animal extends Object{
//类体
}
上述代码声明了动物(Animal)类,它继承了 Object 类。继承 Object 类 extends Object代码可以省略。
类体是类的主体,包括数据和操作,即成员变量和成员方法。下面就来展开介绍一下。
成员变量
声明类体中成员变量语法格式如下:
class className {
[public | protected | private ][static] [final] type variableName; //成员变量
}
其中 type 是成员变量数据类型, variableName 是成员变量名。 type 前的关键字都是
成员变量修饰符,它们说明如下:
1. public、 protected 和 private 修饰符用于封装成员变量。
2. static 修饰符用于声明静态变量,所以静态变量也称为“类变量”。
3. final修饰符用于声明变量,该变量不能被修改。
下面看一个声明成员变量示例:
// Animal.java
public class Animal extends Object{
//动物年龄
int age = 1;
//动物性别
public boolean sex = false;
//动物体重
private double weight = 0.0;
}
上述代码中没有展示静态变量声明,有关静态变量稍后会详细介绍。
成员方法
声明类体中成员方法语法格式如下:
class className {
[public | protected | private ][static] [final | abstract] [native] [synchronized]type methodName([paramList])[throws exceptionList] {
//方法体
}
}
其中 type 是方法返回值数据类型, methodName 是方法名。 type 前的关键字都是方法修饰符,它们说明如下:
1. public、 protected 和 private 修饰符用于封装方法。
2. static 修饰符用于声明静态方法,所以静态方法也称为“类方法”。
3. final | abstract 不能同时修饰方法,final 修饰的方法不能在子类中被覆盖;abstract用来修饰抽象方法,抽象方法必须在子类中被实现。
4. native 修饰的方法,称为“本地方法”,本地方法调用平台本地代码(如: C 或C++编写的代码),不能实现跨平台。
5. synchronized 修饰的方法是同步的,当多线程方式同步方法时,只能串行地执行,保证是线程安全的。
方法声明中还有([paramList])部分,它是方法的参数列表。 throws exceptionList 是声明抛出异常列表。
下面看一个声明方法示例:
public class Animal {// extendsObject {
//动物年龄
int age = 1;
//动物性别
public boolean sex = false;
//动物体重
private double weight = 0.0;
public void eat() { ①
// 方法体
return; ②
}
int run() { ③
// 方法体
return 10; ④
}
protected int getMaxNumber(intnumber1, int number2) { ⑤
// 方法体
if (number1 > number2) {
return number1; ⑥
}
return number2;
}
}
上述代码第①、③、 ⑤行声明了三个方法。 方法在执行完毕后把结果返还给它的调用者,方法体包含“return 返回结果值;”语句, 见代码第④行的“return 10;”,“返回结果值”数据类型与方法的返回值类型要匹配。如果方法返回值类型为 void 时,方法体包含“return;”语句, 见代码第②行, 如果“return;”语句是最后一行则可以省略。
提示 通常return语句通常用在一个方法体的最后,否则会产生编译错误,除非用在if-else语句中,见代码第⑥行。
方法重载(Overload)
例如 String 字符串查找方法 indexOf 有很多不同版本,如图 10-3 所示:
这些相同名字的方法之所以能够在一个类中同时存在,是因为它们的方法参数列表,调用时根据参数列表调用相应重载方法。
提示 方法重载中参数列表不同的含义是: 参数的个数不同或者是参数类型不同。 另外, 返回类型不能用来区分方法重载。
void是无返回值的意思。
比方说
public void walk() {
System.out.print("你好!");
}
如果别的地方调用这个方法 就会打印出 你好!
再看这里:
public String walk() //注意这里的返回类型是String不是void了
{
System.out.print("你好!");
return "哈喽"; //注意这里这个return 如果不写就会报错!
}
原因就是因为上面 的返回类型必须是String型
如果写的是void意思就是不需要返回类型。所以就没必要写return 了
如果方法上面写了某种返回类型 就必须写return后面跟相应的类型值
方法重载示例 MethodOverloading.java 代码如下:
// MethodOverloading.java文件
package com.a51work6;
class MethodOverloading {
void receive(int i) { ①
System.out.println("接收一个int参数");
System.out.println("i =" + i);
}
void receive(int x, int y) { ②
System.out.println("接收两个int参数");
System.out.printf("x = %d, y= %d \r", x, y)
}
int receive(double x, double y) { ③
System.out.println("接收两个double参数");
System.out.printf("x = %f, y= %f \r", x, y);
return 0;
}
}
// HelloWorld.java文件调用MethodOverloading
package com.a51work6;
public class HelloWorld {
public static void main(String[]args) {
MethodOverloading mo = newMethodOverloading();
//调用void receive(int i)
mo.receive(1); ④
//调用void receive(int x, int y)
mo.receive(2, 3); ⑤
//调用void receive(double x, double y)
mo.receive(2.0, 3.3); ⑥
}
}
MethodOverloading 类中有三个相同名字的 receive 方法,在 HelloWorld 的 main 方法中调用 MethodOverloading 的 receive 方法。运行结果如下:
接收一个int参数
i = 1
接收两个int参数
x = 2, y = 3
接收两个double参数
x = 2.000000, y = 3.300000
调用哪一个 receive 方法是根据参数列表决定的。如果参数类型不一致,编译器会进行自动类型转换寻找适合版本的方法,如果没有适合方法,则会发生编译错误。假设删除代码第②行的 void receive(int x, int y)方法, 代码第⑤行的mo.receive(2, 3)语句调用的是void receive(double x, double y)方法,其中 int 类型参数(2 和 3)自动会转换为 double 类型(2.0 和 3.0)再调用。