您的位置:首页 > 编程语言 > Java开发

《Java程序设计基础》 第8章手记Part 2

2016-04-16 10:51 471 查看

第八章内容 Part 2

- …

- 抽象类和抽象方法

- 接口及接口的实现

- 利用接口实现类的多重继承

- 内部库和匿名类

- 包(类库)

抽象类和抽象方法

抽象类是指以修饰符abstract修饰的类。抽象类本身不具备实际的功能,不能使用new运算符,必须通过覆盖的方式实现抽象类的方法。

定义抽象类的语法格式如下:

abstract class Classname {
声明成员变量;

返回值的数据类型 方法名(参数表){    //普通方法
....
}

abstract 返回值的数据类型 方法名(参数表);     //抽象方法,在抽象方法中不能定义方法体
}


抽象方法专门用来根据它的格式来创建和修改新的类,使用时不能直接创建对象,只能通过抽象类派生出新的子类,再由子类来创建对象。

PS:抽象类的子类必须实现父类中所有的抽象方法,或者将自己也声明为抽象的,但最终都需要被实现。你可以这么来理解,抽象父类里的普通方法和成员是父类的财富,而抽象方法相当于负债,继承不仅继承财富,而且继承债务。

Tips:一个类里面只要有一个抽象方法就被认为是抽象类,也即抽象类除了抽象方法还可以有多个普通方法。

1. 由于抽象类是需要被继承的,所以abstract类不能用final修饰。也就是说,一个类不能既是最终类,又是抽象类,即关键字abstract与final不能合用。

2. abstract不能与private、static、final、或native并列修饰同一方法。

3. 抽象类可以有构造方法,且构造方法可以被子类的构造方法调用,但构造方法不能声明为抽象的。

抽象类的应用

这里以实验8_1为例:

//filename Shiyan8_1.java
abstract class Shape {      //定义抽象类
abstract double area();
}

class Circle extends Shape {      //定义子类Circle
private double radius;        //使用private为了体现封装性
private final double PI = 3.14;      //PI是不需要也不应该修改的变量,所以定义为final

public Circle(double r) {      //子类的构造方法
this.radius = r;
}

public double area() {      //重写抽象类的方法area
return PI * radius * radius;
}
}

class Rectangle extends Shape {
private double width;
private double height;

public Rectangle(double w, double h) {
this.width = w;
this.height = h;
}
public double area() {
return width * height;
}
}
public class Shiyan8_1 {
public static void main(String[] args) {
double sum = 0;
Shape shapes[] = new Shape[4];     //定义一个值为引用类型Shape的数组
shapes[0] = new Circle(5.0);     //给每个数组元素赋初值
shapes[1] = new Circle(8.0);
shapes[2] = new Rectangle(4.0,5.0);
shapes[3] = new Rectangle(5.0,8.0);
for(int i = 0; i < shapes.length; i++) {
System.out.println("第" +i +"个图像的面积是:" +shapes[i].area());
}     //遍历整个数组,打印计算出的面积
for (Shape i : shapes) {
sum += i.area();
}
System.out.println("图像的面积和是:" +sum);
}
}


结果如下:



接口

接口和抽象类在结构上非常相似,是Java提供的另一种重要功能,它与抽象类有以下不同:

1. 接口的数据成员都是静态的,并且必须初始化。

2. 接口中的方法必须全部声明为abstract的,也就是说,接口不能像抽象类一样拥有一般的方法,而必须全部是抽象方法。

接口的定义

格式如下:

[public] interface 接口名称 [extends 父接口名列表] {
[public][static][final] 数据类型 成员变量名 = 常量;
...
[public][abstract] 返回值的数据类型 方法名(参数表);
}
其中[]里的内容可以省略,缺省则默认为是括号里的修饰符。


接口的实现与引用

利用接口创建类的过程成为接口的实现,使用关键字implements,而不是extends。

class 类名称 implements 接口名表 {    //可以是多个接口
...
}


一个类实现一个接口时,应注意以下问题:

1. 如果实现某接口的类不是abstract的抽象类,则在类的定义部分必须实现指定接口的所有抽象方法。即非抽象类中不能存在抽象方法。

2. 一个类在实现某接口的抽象方法时,必须使用完全相同的方法头,否则只是定义一个新方法,而不是实现已有的抽象方法。

3. 接口中抽象方法的访问控制符都已经指定是public,所以类在实现方法时必须显式的使用public修饰符否则系统将警告缩小了接口中定义的方法的访问控制符范围。

接口实现举例,实验9_1

interface Shape {
final double PI = 3.14;

abstract double area();
}
public class Cylinder implements Shape {
private double radius;
private int height;
public Cylinder(double r, int h) {
this.radius = r;
this.height = h;
}

public double area() {
return 2 * PI * radius * radius + 2 * PI * radius * height;
}

public static void main(String[] args) {
Cylinder c1 = new Cylinder(4.0, 5);
System.out.println("圆柱体的表面积是:" + c1.area());
}
}


结果如下:



接口的继承

接口和类一样是可以被继承的,但是接口可以多重继承。

利用接口实现类的多重继承

Java只支持类的单重继承机制,不支持类的多重继承,即一个类只能有一个直接父类。但一个类可以同时实现多个接口,这就间接地实现了多重继承。

具体例子参见原书例8.13。

内部类与匿名类

内部类是定义在类中的类,内部类的主要作用是将逻辑上相关的类放到一起;而匿名类是一种特殊的内部类,他没有类名在定义类的同时,就生成该类的一个实例,所以不用取名字,所以被称为匿名内部类。

内部类的例子参见例8.14,详情参阅p141页。

匿名内部类仅一次性使用,不需要起名字,格式如下:

(
new 类名() {
方法名(参数表) {
方法体语句
}
}
).方法名(参数表)


创建匿名内部类的用意,主要是用来弥补内部类中没有定义到的·方法,并可有效的简化程序代码。

具体的例子参见例8.15

包,是Java语言提供的一种区别类名空间的机制,是类的组织方式。源程序没有声明类所在的包时,Java会将类放在默认的包中。

创建包的格式如下:

package 包名1[[.包名2[.包名3]…]

例:
package solo.package.mypackage
表示在solo包中的package子包中定义mypackage包,“.”用来指明文件夹的层次,这个语句应作为源文件的第一条语句

剩下的部分是概念性内容,你需要直接阅读原书的章节。

知乎:Solo | 微博:从流域到海域
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: