Java抽象类和接口(第十三章)

本文介绍了Java中的抽象类和接口。抽象类不可用于创建对象,包含抽象方法,且一个包含抽象方法的类必须声明为抽象类。接口则只包含常量和抽象方法,用于指定相关或不相关类的共同行为。Comparable接口定义了对象比较,Cloneable接口标记对象为可克隆。Java类可以实现多个接口但只能继承一个父类,接口可以继承其他接口。类设计原则强调内聚性、一致性、封装性、清晰性、完整性和实例与静态的区分。
摘要由CSDN通过智能技术生成

一、抽象类

抽象类不可以用于创建对象。抽象类可以包含抽象方法,这些方法将在具体的子类中实现。

在继承的层次结构中,每个新子类都使类变得越来越明确和具体。如果一个子类追溯到父类,类就会变得更通用、更加的不明确。类的设计应该确保父类包含它的子类的共同特征。

有时候,一个父类设计得非常抽象,以至于它都没有任何具体的实例。这样的类称为抽象类。

父类中包含的实现取决于具体的类型的方法,叫抽象方法,在方法头中使用abstract修饰符表示。

在类头中使用abstract修饰符表示该类为抽象类。

在UML图形记号中,抽象类和抽象方法的名字用斜体表示。

抽象类和常规类很像,但是不能使用new操作符创建它的实例。抽象方法只有定义而没有实现。它的实现由子类提供。一个包含抽象方法的类必须声明为抽象类。

抽象类的构造方法定义为protected,因为它只是被子类使用。创建一个具体子类的实例时,它的父类的构造方法被调用以初始化父类中定义的数据域。

1、为什么要使用抽象方法

eg:equal(Object1,Object2)可以比较两个不同方法下的结果

2、抽象类的几点说明

①、抽象方法不能包含在非抽象类中。

②、抽象类是不能使用new操作符来初始化的。

③、包含抽象方法的类必须是抽象的。

④、子类可以覆盖父类的方法并将它定义为abstract。

⑤、即使子类的父类是具体的,这个子类也可以抽象的。

⑥、不能使用new操作符从一个抽象类创建一个实例,但是抽象类可以用作一种数据类型。

二、接口

接口是一种与类相似的结构,只包含常量和抽象方法。

接口在许多方面都与抽象类很相似,但是它的目的是指明相关或者不相关类的多个对象的共同行为。

为了区分接口和类,Java采用下面的语法来定义接口:

修饰符 interface 接口名{

/**  常量声明  **/

/** 方法签名  **/

}

在Java中,接口被看作是一种特殊的类。就像常规类一样,每个接口都被编译为独立的字节码文件。与抽象类相似,不能使用new操作符创建接口的实例。

可以使用Edible接口来明确一个对象是否可食用。需要使用implements关键字让对象的类实现这个接口来完成。eg:class Chicken extends Animal implements Edible

类和接口之间的关系称为接口继承。因为接口继承和类继承本质上是相同的,都简称为继承。

三、Comparable接口

Comparable接口定义了compareTo,用于比较对象。

Comparable接口的定义:

//Interface for comparing objects,defined in java.lang
package java.lang;
public interface Comparable<E>{
    public int compareTO(E o);
}

compareTo方法判断这个对象相对于相对于给定对象o的顺序,并且当这个对象小于、等于或大于给定对象o时,分别返回负整数、0或正整数。

Comparable接口是一个泛型接口。在实现该接口时,泛型类型E被替换成一种具体的类型。

如果对象是Comparable接口类型的实例,Java API中的java.util.Arrays.sort(Object[])方法就可以使用compareTo方法来对数组中的对象进行比较和排序。

四、Cloneable接口

Cloneable接口给出了一个可克隆的对象。定义:

package java.lang

public interfacen Cloneable{
}

这个接口是空的。一个带空体的接口称为标记接口。一个标记接口既不包括常量也不包括方法。它用来表示一个类拥有某些特征的属性。实现Cloneable接口的类标记为可克隆的,而且它的对象可以使用在Object类中定义clone()方法克隆。

五、接口和抽象类

一个类可以实现多个接口,但是只能继承一个父类。

接口与抽象类的不同点
变量构造方法方法
抽象类无限制子类通过构造方法调用构造方法,抽象类不能用new操作符实例化无限制
接口所有变量必须是public static final没有构造方法。接口不能用new操作符实例化所有方法必须是公共的抽象实例的方法

Java只允许为类的扩展做单一继承,但是允许使用接口做多重扩展。

使用关键字extends,接口可以继承其他接口。这样的接口称为子接口。eg:

public interface NewInterface extends Interface1,...,InterfaceN{
    //constans and abstract methods
}

抽象类和接口都是用来明确多个对象的共同特征的。一般来说,清晰描述父子关系的强的“是一种”的关系应该使用类建模。弱的“是一种”的关系也称为类属关系,它表明对象拥有某种属性,可以用接口来建模。

通常,推荐使用接口而非抽象类,因为接口可以定义非相关类共有的父类型。接口比类更加灵活。

六、类的设计原则

1、内聚性

类应该描述一个单一的实体,而所有的类操作应该在逻辑上相互配合,支持一个一致的目的。

2、一致性

遵循标准Java程序设计风格和命名习惯。为类、数据域和方法选取具有信息的名字。通常的风格是将数据声明置于构造方法之前,并且将构造方法置于方法之前。

选择名字要保持一致。给类似的操作选择不同的名字并非良好的实践。

一般来说,应该具有一致性地提供一个公共无参构造方法,用于构建默认实例。如果一个类不支持无参的构造方法,要用文档写出原因。如果没有显示定义构造方法,即假定有一个空方法体的公共无参构造方法。

如果不想让用户创建类的对象,可以在类中声明一个私有的构造方法,Math类就是如此。

3、封装性

一个类应该使用private修饰符隐藏其数据,以免用户直接访问它。这使得类更易于维护。

只在希望数据域可读的情况下,才提供get方法;也只在希望数据域可更新的情况下,才提供set方法。

4、清晰性

为使设计清晰,内聚性、一致性和封装性都是很好的设计原则。除此之外,类应该有一个很清晰的合约,从而易于解释和理解。

用户可以以各种不同的组合、顺序,以及在各种环境中结合使用多个类。

方法应在不产生混淆的情况下进行直观定义。

不应该声明一个来自其他数据域的数据域。

5、完整性

类是为许多不同用户的使用而设计的。为了能在一个广泛的应用中使用,一个类应该通过属性和方法提供多种方案以适应用户的不同需求。

6、实例和静态

依赖于类的具体实例的变量或方法必须是一个实例变量或方法。如果一个变量被类的所有实例所共享,那就应该将它声明为静态的。如果方法不依赖于某个具体的实例,那就应该将它声明为静态方法。

应该总是使用类名(而不是引用变量)引用静态变量和方法,以增强可读性并避免错误。

不要从构造方法传入参数来初始化静态数据域。最好使用set方法改变静态数据域。

实例和静态是面向对象程序设计不可或缺的部分。数据域或方法要么是实例的,要么是静态的。不要错误地忽视静态数据域或方法。

构造方法永远都是实例方法,因为它是用来创建具体实例的。一个静态变量或方法可以从实例方法中调用,但是不能从静态方法中调用实例变量或方法。

7、继承与聚合

继承和聚合之间的差异,就是is-a(是一种)和has-a(具有)之间的关系。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值