抽象类、接口和内部类(上)

来源:互联网 发布:通联支付网络给我打钱 编辑:程序博客网 时间:2024/06/16 22:36
Top
  1. 抽象类、接口和内部类(上)

1. 抽象类、接口和内部类(上)

1.1. 使用抽象类

1.1.1. 抽象方法和抽象类

由abstract修饰的方法为抽象方法,抽象方法即只有方法的定义,没有方法体实现,用一个分号结尾。即方法五要素中,抽象方法缺少了一个要素(即:方法体)。也可以将抽象方法理解为不完整的方法。

若将抽象方法包含在类中,则该类也应该为抽象的,可以理解为,该类也不完整。抽象类由abstract关键字声明。

抽象类是不能实例化对象的,而一个类不能实例化是没有意义的,所以,需要定义类来继承抽象类,而如果一个类继承了抽象类,则其必须重写其抽象方法(变不完整为完整),除非该类也声明为抽象类。看下面的代码,定义了抽象方法和抽象类:

copytextpop-up
  1. abstract class Shape {
  2. private double c;
  3. public Shape(double c) {
  4. this.c = c;
  5. }
  6. public abstract double area();
  7. }
abstract class Shape {     private double c;     public Shape(double c) {         this.c = c;     }     public abstract double area();} 

通过上面的代码可以看到,area()方法没有方法体(连大括号也不存在),由abstract修饰,此为抽象方法。而Shape方法也由abstract修饰,即为抽象类。

1.1.2. 抽象类不可以实例化

抽象类不可以实例化,若Shape是抽象类的话,下面的代码是错误的:

copytextpop-up
  1. Shape s1 = new Shape();
    Shape s1 = new Shape();

即使一个类中没有抽象方法,也可以将其定义为抽象类,同样,该类不可以实例化。

需要注意一点:abstract和final关键字不可以同时用于修饰一个类,因为final关键字使得类不可继承,而abstract修饰的类如果不可以继承将没有任何意义。两者放在一起,会起冲突。

1.1.3. 继承抽象类

一个类继承抽象类后,必须实现其抽象方法,不同的子类可以有不同的实现。看下面的代码,Square类与Circle类都继承自Shape类,并分别实现了重写的area()方法,只是其具体实现的代码不同:

copytextpop-up
  1. class Square extends Shape {
  2. private double c;
  3. public Square(double c) {
  4. super(c);
  5. }
  6. public double area() {
  7. return 0.0625*c*c;
  8. }
  9. }
  10. class Circle extends Shape{
  11. private double c;
  12. public Circle(double c) {
  13. super(c);
  14. }
  15. public double area() {
  16. return 0.0796*c*c;
  17. }
  18. }
class Square extends Shape {     private double c;     public Square(double c) {         super(c);     }     public double area() {          return 0.0625*c*c;     }}class Circle extends Shape{     private double c;     public Circle(double c) {          super(c);          }      public double area() {          return 0.0796*c*c;     }} 

1.1.4. 抽象类的意义

定义抽象类的意义在于:

  • 为其子类提供一个公共的类型(父类引用指向子类对象);
  • 封装子类中的重复内容(成员变量和方法);
  • 定义有抽象方法,子类虽然有不同的实现,但该方法的定义是一致的。(子类需要实现此抽象方法)。

看如下的代码:

copytextpop-up
  1. Shape[] sArr = {new Circle(100), new Square(100),
  2.      new Circle(200), new Square(150) };
  3. for(int i=0; i<sArr.length; i++) {
  4. Shape shape = sArr[i];
  5. System.out.println(shape.area());
  6. }
Shape[] sArr = {new Circle(100),  new Square(100),              new Circle(200), new Square(150) };for(int i=0; i<sArr.length; i++) {    Shape shape = sArr[i];    System.out.println(shape.area());} 

通过上面的代码可以看出,以Shape类型的引用访问其子类,所有子类都会有area方法,只是其具体的实现各不一样。

1.2. 使用接口

1.2.1. 定义一个接口

接口可以看成是特殊的抽象类。即只包含抽象方法和常量的抽象类。可以通过interface关键字来定义接口。看如下代码:

copytextpop-up
  1. interface Runner {
  2. public static int DEFAULT_SPEED = 100
  3. public void run();
  4. }
interface Runner {     public static int DEFAULT_SPEED = 100    public void run(); } 

注意,run()方法,此处可以省略public abstract。因其默认就是public abstract的。

1.2.2. 实现接口

与继承不同,一个类可以实现多个接口,实现的接口直接用逗号分隔。当然,该类需要实现这些接口中定义的所有方法;

一个类可以通过implements关键字”实现”接口。一个类实现了某个接口后必须实现该接口中定义的所有方法。看下面的代码,类实现了接口并实现了方法:

copytextpop-up
  1. class AmericanCurl implements Runner ,{
  2. public void run() {
  3. System.out.println("run...");
  4. }
  5. }
class AmericanCurl implements Runner , … {     public void run() {        System.out.println("run...");    } } 

另外需要说明的一点,接口可以作为一种类型声明变量,一个接口类型的变量可以引用实现了该接口的类的对象;通过该变量可以调用该接口中定义的方法(具体的实现类提供了方法的实现)。代码如下所示:

copytextpop-up
  1. Runner runner = new AmericanCurl();
Runner runner = new AmericanCurl(); 

此句代码为,一个接口类型变量,引用了子类的对象。调用时,调用的是子类对象的具体的实现。

1.2.3. 接口的继承

接口间可以存在继承关系,一个接口可以通过extends关键字继承另外一个接口。子接口继承了父接口中定义的所有方法。代码如下所示:

copytextpop-up
  1. interface Runner {
  2. public void run();
  3. }
  4. interface Hunter extends Runner {
  5. public void hunt();
  6. }
  7. class AmericanCurl implements Hunter {
  8. public void run() {… … …}
  9. public void hunt() {… … …}
  10. }
interface Runner {    public void run();}interface Hunter  extends Runner {    public void hunt();}class AmericanCurl implements Hunter {    public void run() {… … …}     public void hunt() {… … …} } 

说明:AmericanCurl实现了Hunter,必须实现Hunter接口中的hunt方法以及其父接口Runner中的run方法。

1.2.4. 接口和抽象类的区别

图 -1

从图1中可以看出,达内职员类为抽象类,企业技术顾问、技术图书作者为两个接口。达内讲师类继承了抽象类达内职员,并实现了企业技术顾问和技术图书作者两个接口。而达内项目经理只继承了抽象类达内职员。通过分析,可以总结出如下几点抽象类和接口的区别:

  • 一个类只能继承一个抽象类,但可以实现多个接口。
  • 抽象类中可以包含抽象方法和非抽象方法,而接口中的所有方法均为抽象的。
  • 子类继承抽象类必须实现抽象类中所有抽象方法,否则子类也必须是抽象类。而子类实现接口则必须实现接口中的所有抽象方法。
原创粉丝点击