5.7 抽象类 与 接口

5.7.1抽象类

在面向对象的概念中,所有的对象都是通过类来描绘的,但反过来的话,并不是所有的类都是用来描绘对象的。 如果一个类中没有包含足够的信息来描绘一个具体的对象,这样的类就叫抽象类。
抽象类往往用来表征 问题分析过程中得出的抽象概念,对一系列看上去不同,但是本质上相同的具体概念的抽象。例如,进行图形编辑软件的开发时,会发现问题领域存在着圆,三角形 这样一些概念,他们是不同的,但是他们又都属于现状这样一个概念,现状这个概念在问题域领域是不存在的,他就是一个抽象概念。正是因为抽象的概念在问题领域没有对应的对象,所以用来表示抽象概念的抽象类是不能够被实例化的。

1.抽象类的定义

抽象类需要用abstract来修饰 ,定义语法如下:

abstract class <类名> [extends<父类>][implements<接口名>{
    <类主体>
}]

【例5-22】定义所有动物的抽象类。

Ex5_22_abstract.java

package com.ch5;

public class Ex5_22_abstract {

    public static void main(String[] args) {
        // Animal a = new Animal()  //  A行 ,禁止实例化抽象类
        Cat2 tom = new Cat2();
        tom.eat();
        tom.run();
    }
}

abstract class Animal{
    String eyeColor;
    String furColor;
    int age;

    public Animal(){
        age = 0;
    }

    abstract void eat();

    abstract void run();

}

class Cat2 extends Animal{
    void run(){
        System.out.println("猫扑");
    }

    void eat() {
        System.out.println("吃老鼠");

    }
}

运行结果如下:
图片

(1)抽象类与抽象方法。
抽象方法属于一种不完整的方法,只有一个声明部分,没有类主体。声明抽象方法的语法如下:

abstract  <方法返回值类型><方法名>([<参数列表>]);

例5-22中Animal类中 eat , run 方法均属于抽象方法。
包含抽象方法的类一定是抽象类,但是抽象类不一定包含抽象方法。也就是说,即使不包含任何抽象方法,也可将一个类声明为抽象类。
(2)抽象类不能被实例化。抽象类不能使用new关键字创建实例化对象。

2.抽象类的继承

如果一个类A需要继承抽象类,则该类 要么实现抽象类中定义的所有抽象方法,要么 该类也被修饰为抽象类(2选一)。也就是说,抽象类的子类如果只实现父类的部分抽象方法,子类也必须声明为抽象类。
例如:

abstract class Mammal extends Animal{
    int viviparousAmount;
}

Mammal 类没有实现父类Animal中包含的抽象方法,所有将Mammal 声明为抽象类。

5.7.2 接口(一种特殊的类,用来被继承,被实现的)

接口(interface)是java所提供的一种重要结构。接口是一种特殊的类,但接口与类有本质的区别。
类有成员变量和成员方法,而接口却只有常量和抽象方法,也就是说,接口的成员变量必须初始化,所有方法必须声明为abstract方法。

1. 接口的定义

接口通过关键字interface来定义,一般形式如下:

[接口修饰符]interface<接口名>[extends<父类接口列表>]{
    接口体
}

(1)接口修饰符:接口修饰符为接口访问权限,有public和默认两种类型。
public指明任何类均可以使用这个接口。
在默认情况下,只有与该接口在同一包中的类才可以访问这个接口,其他包中的类无法访问该接口。
(2)接口名:接口名为合法的java语言标识符。
(3)父类接口列表:一个接口可以继承其他接口,通过关键字extends 来实现,其语法与类的继承相同。被继承的类接口称为父类接口,当有多个父类接口时,用“ , ”分隔。
(4)接口体:接口体中包括接口中需要说明的 常量 和 抽象方法。
由于接口中只有常量,所以接口中的成员变量只能定义为static 和final型,在类实现接口时不能被修改,而且必须用常量初始化。接口体中的方法说明 与 类体中的方法说明形式不一样,由于接口体中的方法为抽象方法,所以没有方法体。抽象方法的关键字abstract可以省略,同时成员变量的关键字final也可以省略,接口接口体中的方法多为public权限。

2. 接口的实现

用implements子句表示类实现某个接口。一个类可以同时实现多个接口,接口之间用逗号分隔。
在类体中可以使用接口中定义的常量,由于接口中定义的方法为抽象方法,所以必须在类体中加入 要实现接口方法的代码,如果一个接口是从别的一个或多个父类接口中继承而来的,则在类体中必须加入实现该接口及父接口中所有方法的代码
在实现一个接口时,类中对方法的定义要和接口中的相应方法的定义相匹配,其方法名,方法返回值类型,方法的访问权限和参数数目与类型信息要一致。

3. 接口与多重继承

与类一样,接口可以使用extends子句生成子接口。原来的接口称为基本接口(base interface)或父接口(super interface),扩展出的接口称为派生接口或子接口。
通过这种机制,派生接口不仅保留父接口成员,同时也可以新加入新的成员以满足实际问题的需要。

与类不同的是,一个接口可以扩展多个接口,继承他们所有的属性和方法;而一个类只能扩展一个类。显然,接口不能扩展类,接口的方法必须全是抽象的。例如:

interface A extends  B{...}

这条语句表示定义了接口A并继承了接口B,使A称为B的子接口,并且A具有B的所有属性和方法。接口在继承的过程中可能会出现以下情况:
(1)方法重名(多继承的时候)。如果两个方法万千一样,只保留一个;如果两个方法有不同的参数(类型或个数),那么子接口中包括两个方法,方法被重载;如果两个方法仅在返回值上不同,出现错误。
(2)常量重名。 父接口两个重名的常量全部保留在子接口中,并用原来的接口名作为前缀。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值